[PATCH v2] IIO ADC support for AD7923

2013-02-12 Thread Christophe Leroy
This patch adds support for Analog Devices AD7923 ADC in the IIO Subsystem.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -urN linux-next-e347c98/drivers/iio/adc/Kconfig 
linux-next-e347c98.new/drivers/iio/adc/Kconfig
--- linux-next-e347c98/drivers/iio/adc/Kconfig  2013-02-08 05:22:35.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/Kconfig  2013-02-12 
13:02:52.0 +0100
@@ -30,6 +30,18 @@
  To compile this driver as a module, choose M here: the
  module will be called ad7298.
 
+config AD7923
+   tristate "Analog Devices AD7923 ADC driver"
+   depends on SPI
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
+   help
+ Say yes here to build support for Analog Devices AD7923
+ 4 Channel ADC with temperature sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7923.
+
 config AD7791
tristate "Analog Devices AD7791 ADC driver"
depends on SPI
diff -urN linux-next-e347c98/drivers/iio/adc/Makefile 
linux-next-e347c98.new/drivers/iio/adc/Makefile
--- linux-next-e347c98/drivers/iio/adc/Makefile 2013-02-08 05:22:35.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/Makefile 2013-02-12 
13:03:02.0 +0100
@@ -5,6 +5,7 @@
 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AD7298) += ad7298.o
+obj-$(CONFIG_AD7923) += ad7923.o
 obj-$(CONFIG_AD7476) += ad7476.o
 obj-$(CONFIG_AD7791) += ad7791.o
 obj-$(CONFIG_AD7793) += ad7793.o
diff -urN linux-next-e347c98/drivers/iio/adc/ad7923.c 
linux-next-e347c98.new/drivers/iio/adc/ad7923.c
--- linux-next-e347c98/drivers/iio/adc/ad7923.c 1970-01-01 01:00:00.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/ad7923.c 2013-02-12 
15:16:29.0 +0100
@@ -0,0 +1,298 @@
+/*
+ * AD7923 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define AD7923_WRITE_CR(1 << 11)   /* write control 
register */
+#define AD7923_RANGE   (1 << 1)/* range to REFin */
+#define AD7923_CODING  (1 << 0)/* coding is straight binary */
+#define AD7923_PM_MODE_AS  (1) /* auto shutdown */
+#define AD7923_PM_MODE_FS  (2) /* full shutdown */
+#define AD7923_PM_MODE_OPS (3) /* normal operation */
+#define AD7923_CHANNEL_0   (0) /* analog input 0 */
+#define AD7923_CHANNEL_1   (1) /* analog input 1 */
+#define AD7923_CHANNEL_2   (2) /* analog input 2 */
+#define AD7923_CHANNEL_3   (3) /* analog input 3 */
+#define AD7923_SEQUENCE_OFF(0) /* no sequence fonction */
+#define AD7923_SEQUENCE_PROTECT(2) /* no interrupt write 
cycle */
+#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
+
+#define AD7923_MAX_CHAN4
+
+#define AD7923_PM_MODE_WRITE(mode) (mode << 4) /* write mode */
+#define AD7923_CHANNEL_WRITE(channel)  (channel << 6)  /* write channel */
+#define AD7923_SEQUENCE_WRITE(sequence)(((sequence & 1) << 3) \
+   + ((sequence & 2) << 9))
+   /* write sequence fonction */
+/* left shift for CR : bit 11 transmit in first */
+#define AD7923_SHIFT_REGISTER  4
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define EXTRACT(val, dec, bits)((val >> dec) & ((1 << bits) - 
1))
+
+struct ad7923_state {
+   struct spi_device   *spi;
+   struct spi_transfer ring_xfer[6];
+   struct spi_transfer scan_single_xfer[2];
+   struct spi_message  ring_msg;
+   struct spi_message  scan_single_msg;
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   __be16  rx_buf[4] cacheline_aligned;
+   __be16  tx_buf[2];
+};
+
+#define AD7923_V_CHAN(index)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = index,   \
+   .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
+  

[PATCH v2] Enhanced support for MPC8xx/8xxx watchdog

2013-02-28 Thread Christophe Leroy
This patch modifies the behaviour of the MPC8xx/8xxx watchdog. On the MPC8xx,
at 133Mhz, the maximum timeout of the watchdog timer is 1s, which means it must
be pinged twice a second. This is not in line with the Linux watchdog concept
which is based on a default watchdog timeout around 60s.
This patch introduces an intermediate layer between the CPU and the userspace.
The kernel pings the watchdog at the required frequency at the condition that
userspace tools refresh it regularly.
Existing parameter 'timeout' is renamed 'hw_time'.
The new parameter 'timeout' allows to set up the userspace timeout.
The driver also implements the WDIOC_SETTIMEOUT ioctl.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/drivers/watchdog/mpc8xxx_wdt.c 
linux/drivers/watchdog/mpc8xxx_wdt.c
--- linux-3.7.9/drivers/watchdog/mpc8xxx_wdt.c  2013-02-17 19:53:32.0 
+0100
+++ linux/drivers/watchdog/mpc8xxx_wdt.c2013-02-27 16:00:07.0 
+0100
@@ -52,10 +52,17 @@
 static struct mpc8xxx_wdt __iomem *wd_base;
 static int mpc8xxx_wdt_init_late(void);
 
-static u16 timeout = 0x;
-module_param(timeout, ushort, 0);
+#define WD_TIMO 10 /* Default timeout = 10 seconds */
+
+static uint timeout = WD_TIMO;
+module_param(timeout, uint, 0);
 MODULE_PARM_DESC(timeout,
-   "Watchdog timeout in ticks. (0swcrr, tmp);
 
-   del_timer_sync(&wdt_timer);
+   wdt_auto = 0;
 
return nonseekable_open(inode, file);
 }
@@ -138,7 +158,8 @@
 static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
 {
if (!nowayout)
-   mpc8xxx_wdt_timer_ping(0);
+   wdt_auto = 1;
+
else
mpc8xxx_wdt_pr_warn("watchdog closed");
clear_bit(0, &wdt_is_open);
@@ -163,10 +184,12 @@
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:
-   mpc8xxx_wdt_keepalive();
+   mpc8xxx_wdt_sw_keepalive();
return 0;
case WDIOC_GETTIMEOUT:
-   return put_user(timeout_sec, p);
+   return put_user(timeout, p);
+   case WDIOC_SETTIMEOUT:
+   return get_user(timeout, p);
default:
return -ENOTTY;
}
@@ -215,12 +238,14 @@
ret = -ENOSYS;
goto err_unmap;
}
+   if (enabled)
+   hw_timo = in_be32(&wd_base->swcrr) >> 16;
 
/* Calculate the timeout in seconds */
if (prescale)
-   timeout_sec = (timeout * wdt_type->prescaler) / freq;
+   hw_timo_sec = (hw_timo * wdt_type->prescaler) / freq;
else
-   timeout_sec = timeout / freq;
+   hw_timo_sec = hw_timo / freq;
 
 #ifdef MODULE
ret = mpc8xxx_wdt_init_late();
@@ -228,8 +253,8 @@
goto err_unmap;
 #endif
 
-   pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d 
seconds)\n",
-   reset ? "reset" : "interrupt", timeout, timeout_sec);
+   pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout = %d (%d 
seconds)\n",
+   reset ? "reset" : "interrupt", hw_timo, hw_timo_sec);
 
/*
 * If the watchdog was previously enabled or we're running on
@@ -273,6 +298,7 @@
.compatible = "fsl,mpc823-wdt",
.data = &(struct mpc8xxx_wdt_type) {
.prescaler = 0x800,
+   .hw_enabled = true,
},
},
{},
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Unset LANG in setlocalversion script

2013-02-21 Thread Christophe Leroy
This patch allows the use of setlocalversion script regardless of the LANG
parameter. Otherwise, the `svn info 2>/dev/null | grep '^Last Changed Rev'`
returns nothing because for instance, in French the text 'Last Changed Rev'
is replaced by 'Révision de la dernière modification'

Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/scripts/setlocalversion linux/scripts/setlocalversion
--- linux-3.7.9/scripts/setlocalversion 2013-02-17 19:53:32.0 +0100
+++ linux/scripts/setlocalversion   2012-11-03 03:15:32.0 +0100
@@ -9,6 +9,8 @@
 #
 #
 
+unset LANG
+
 usage() {
echo "Usage: $0 [--save-scmversion] [srctree]" >&2
exit 1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Handling of IRQ in MPC8xx GPIO

2013-02-21 Thread Christophe Leroy
This patch allows the use IRQ to notify the change of GPIO status on the MPC8xx
CPM IO ports. This then allows to associate IRQs to GPIOs in the Device Tree. 
Ex:
CPM1_PIO_C: gpio-controller@960 {
#gpio-cells = <2>;
compatible = "fsl,cpm1-pario-bank-c";
reg = <0x960 0x10>;
interrupts = <255 255 255 255 1 2 6 9 10 11 14 15 23 24 26 31>;
interrupt-parent = <&CPM_PIC>;
gpio-controller;
    };

Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/arch/powerpc/include/asm/cpm1.h 
linux/arch/powerpc/include/asm/cpm1.h
--- linux-3.7.9/arch/powerpc/include/asm/cpm1.h 2013-02-17 19:53:32.0 
+0100
+++ linux/arch/powerpc/include/asm/cpm1.h   2012-11-03 03:18:35.0 
+0100
@@ -560,6 +560,8 @@
 #define CPM_PIN_SECONDARY 2
 #define CPM_PIN_GPIO  4
 #define CPM_PIN_OPENDRAIN 8
+#define CPM_PIN_FALLEDGE  16
+#define CPM_PIN_ANYEDGE   0
 
 enum cpm_port {
CPM_PORTA,
diff -ur linux-3.7.9/arch/powerpc/sysdev/cpm1.c linux/arch/powerpc/sysdev/cpm1.c
--- linux-3.7.9/arch/powerpc/sysdev/cpm1.c  2013-02-17 19:53:32.0 
+0100
+++ linux/arch/powerpc/sysdev/cpm1.c2013-02-21 15:52:51.0 +0100
@@ -375,6 +375,10 @@
setbits16(&iop->odr_sor, pin);
else
clrbits16(&iop->odr_sor, pin);
+   if (flags & CPM_PIN_FALLEDGE)
+   setbits16(&iop->intr, pin);
+   else
+   clrbits16(&iop->intr, pin);
}
 }
 
@@ -526,6 +530,9 @@
 
/* shadowed data register to clear/set bits safely */
u16 cpdata;
+
+   /* IRQ associated with Pins when relevant */
+   int irq[16];
 };
 
 static inline struct cpm1_gpio16_chip *
@@ -581,6 +588,30 @@
spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 }
 
+static int __cpm1_gpio16_to_irq(struct of_mm_gpio_chip *mm_gc,
+   unsigned int gpio)
+{
+   struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+
+   return cpm1_gc->irq[gpio] ? cpm1_gc->irq[gpio] : -ENXIO;
+}
+
+static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
+{
+   struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+   struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+   unsigned long flags;
+   int ret;
+
+   spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+   ret = __cpm1_gpio16_to_irq(mm_gc, gpio);
+
+   spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+
+   return ret;
+}
+
 static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int 
val)
 {
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
@@ -621,6 +652,7 @@
struct cpm1_gpio16_chip *cpm1_gc;
struct of_mm_gpio_chip *mm_gc;
struct gpio_chip *gc;
+   int i;
 
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
if (!cpm1_gc)
@@ -628,6 +660,9 @@
 
spin_lock_init(&cpm1_gc->lock);
 
+   for (i = 0; i < 16; i++)
+   cpm1_gc->irq[i] = irq_of_parse_and_map(np, i);
+
mm_gc = &cpm1_gc->mm_gc;
gc = &mm_gc->gc;
 
@@ -637,6 +672,7 @@
gc->direction_output = cpm1_gpio16_dir_out;
gc->get = cpm1_gpio16_get;
gc->set = cpm1_gpio16_set;
+   gc->to_irq = cpm1_gpio16_to_irq;
 
return of_mm_gpiochip_add(np, mm_gc);
 }
diff -ur linux-3.7.9/kernel/irq/irqdomain.c linux/kernel/irq/irqdomain.c
--- linux-3.7.9/kernel/irq/irqdomain.c  2013-02-17 19:53:32.0 +0100
+++ linux/kernel/irq/irqdomain.c2012-12-13 19:52:38.0 +0100
@@ -763,7 +763,8 @@
BUG_ON(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR);
 
/* Check revmap bounds; complain if exceeded */
-   if (WARN_ON(hwirq >= domain->revmap_data.linear.size))
+   /* 255 is a trick to allow UNDEF value in DTS */
+   if (hwirq == 255 || WARN_ON(hwirq >= domain->revmap_data.linear.size))
return 0;
 
return domain->revmap_data.linear.revmap[hwirq];
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] Unset langage specific variables in setlocalversion script

2013-02-22 Thread Christophe Leroy
This patch allows the use of setlocalversion script regardless of the language
parameters. Otherwise, the `svn info 2>/dev/null | grep '^Last Changed Rev'`
returns nothing because for instance, in French the text 'Last Changed Rev'
is replaced by 'Révision de la dernière modification'

Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/scripts/setlocalversion linux/scripts/setlocalversion
--- linux-3.7.9/scripts/setlocalversion 2013-02-17 19:53:32.0 +0100
+++ linux/scripts/setlocalversion   2013-02-22 03:37:31.0 +0100
@@ -108,7 +108,7 @@
fi
 
# Check for svn and a svn repo.
-   if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
+   if rev=`LANG= LC_ALL= LC_MESSAGES=C svn info 2>/dev/null | grep '^Last 
Changed Rev'`; then
rev=`echo $rev | awk '{print $NF}'`
printf -- '-svn%s' "$rev"
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Adds support for Open Firmware in MAX730x GPIO Driver

2013-02-22 Thread Christophe Leroy
This patch allows the use of the MAX730x Driver on systems using
the Open Firmware platform format

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/drivers/gpio/gpio-max7301.c 
linux/drivers/gpio/gpio-max7301.c
--- linux-3.7.9/drivers/gpio/gpio-max7301.c 2013-02-17 19:53:32.0 
+0100
+++ linux/drivers/gpio/gpio-max7301.c   2013-02-17 12:57:40.0 +0100
@@ -56,7 +56,8 @@
int ret;
 
/* bits_per_word cannot be configured in platform data */
-   spi->bits_per_word = 16;
+   if (spi->dev.platform_data)
+   spi->bits_per_word = 16;
ret = spi_setup(spi);
if (ret < 0)
return ret;
diff -ur linux-3.7.9/drivers/gpio/gpio-max730x.c 
linux/drivers/gpio/gpio-max730x.c
--- linux-3.7.9/drivers/gpio/gpio-max730x.c 2013-02-17 19:53:32.0 
+0100
+++ linux/drivers/gpio/gpio-max730x.c   2013-02-22 10:15:46.0 +0100
@@ -163,12 +163,13 @@
 int __devinit __max730x_probe(struct max7301 *ts)
 {
struct device *dev = ts->dev;
+   struct device_node *np = dev->of_node;
struct max7301_platform_data *pdata;
int i, ret;
 
pdata = dev->platform_data;
-   if (!pdata || !pdata->base) {
-   dev_err(dev, "incorrect or missing platform data\n");
+   if ((!pdata || !pdata->base) && !np) {
+   dev_err(dev, "No platform data nor Device Tree found\n");
return -EINVAL;
}
 
@@ -178,7 +179,6 @@
/* Power up the chip and disable IRQ output */
ts->write(dev, 0x04, 0x01);
 
-   ts->input_pullup_active = pdata->input_pullup_active;
ts->chip.label = dev->driver->name;
 
ts->chip.direction_input = max7301_direction_input;
@@ -186,7 +186,12 @@
ts->chip.direction_output = max7301_direction_output;
ts->chip.set = max7301_set;
 
-   ts->chip.base = pdata->base;
+   if (pdata) {
+   ts->input_pullup_active = pdata->input_pullup_active;
+   ts->chip.base = pdata->base;
+   } else {
+   ts->chip.base = -1;
+   }
ts->chip.ngpio = PIN_NUMBER;
ts->chip.can_sleep = 1;
ts->chip.dev = dev;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/2] hwmon/lm70: changes to allow 4w with LM70 and add LM71/LM74

2012-09-04 Thread Christophe Leroy
Hello,

The two following patches do:
1) Allow the use of NS LM70 with a 4 wire SPI bus too, since the component 
allows both configuration
2) Adds support for NS LM71 and LM74

Regards
Christophe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] hwmon/lm70: Allow 4wire SPI bus with LM70

2012-09-04 Thread Christophe Leroy
Removing the 3wire limitation on LM70 as the component also allows
operation on 4wire SPI bus

Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/hwmon/lm70.c linux-3.5/drivers/hwmon/lm70.c
--- linux-3.5-vanilla/drivers/hwmon/lm70.c  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/lm70.c  2012-08-25 00:35:40.0 +0200
@@ -143,10 +143,6 @@
if (spi->mode & (SPI_CPOL | SPI_CPHA))
return -EINVAL;
 
-   /* 3-wire link (shared SI/SO) for LM70 */
-   if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE))
-   return -EINVAL;
-
/* NOTE:  we assume 8-bit words, and convert to 16 bits manually */
 
p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
diff -u linux-3.5-vanilla/Documentation/hwmon/lm70 
linux-3.5/Documentation/hwmon/lm70
--- linux-3.5-vanilla/Documentation/hwmon/lm70  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/Documentation/hwmon/lm70  2012-08-25 00:37:15.0 +0200
@@ -31,9 +31,8 @@
 with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
 and its associated documentation.
 
-The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
-face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
-lution).
+The TMP121/TMP123 are very similar; main difference is 13-bit temperature
+data (0.0625 degrees celsius resolution).
 
 Thanks to
 -
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] hwmon/lm70: Adds support for LM71 and LM74

2012-09-04 Thread Christophe Leroy
Adding support for LM74 and LM71 chips

Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/hwmon/Kconfig linux-3.5/drivers/hwmon/Kconfig
--- linux-3.5-vanilla/drivers/hwmon/Kconfig 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/Kconfig 2012-08-25 00:44:05.0 +0200
@@ -530,12 +530,12 @@
  will be called lm63.
 
 config SENSORS_LM70
-   tristate "National Semiconductor LM70 / Texas Instruments TMP121"
+   tristate "National Semiconductor LM70 and compatibles"
depends on SPI_MASTER
help
  If you say yes here you get support for the National Semiconductor
- LM70 and Texas Instruments TMP121/TMP123 digital temperature
- sensor chips.
+ LM70, LM71, LM74 and Texas Instruments TMP121/TMP123 digital tempera-
+ ture sensor chips.
 
  This driver can also be built as a module.  If so, the module
  will be called lm70.
diff -u linux-3.5-vanilla/drivers/hwmon/lm70.c linux-3.5/drivers/hwmon/lm70.c
--- linux-3.5-vanilla/drivers/hwmon/lm70.c  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/lm70.c  2012-08-25 00:49:46.0 +0200
@@ -43,6 +43,8 @@
 
 #define LM70_CHIP_LM70 0   /* original NS LM70 */
 #define LM70_CHIP_TMP121   1   /* TI TMP121/TMP123 */
+#define LM70_CHIP_LM71 2   /* NS LM71 */
+#define LM70_CHIP_LM74 3   /* NS LM71 */
 
 struct lm70 {
struct device *hwmon_dev;
@@ -88,9 +90,13 @@
 * Celsius.
 * So it's equivalent to multiplying by 0.25 * 1000 = 250.
 *
-* TMP121/TMP123:
+* LM74 and TMP121/TMP123:
 * 13 bits of 2's complement data, discard LSB 3 bits,
 * resolution 0.0625 degrees celsius.
+*
+* LM71:
+* 14 bits of 2's complement data, discard LSB 2 bits,
+* resolution 0.0312 degrees celsius.
 */
switch (p_lm70->chip) {
case LM70_CHIP_LM70:
@@ -98,8 +104,13 @@
break;
 
case LM70_CHIP_TMP121:
+   case LM70_CHIP_LM74:
val = ((int)raw / 8) * 625 / 10;
break;
+
+   case LM70_CHIP_LM71:
+   val = ((int)raw / 4) * 3125 / 100;
+   break;
}
 
status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
@@ -123,6 +134,12 @@
case LM70_CHIP_TMP121:
ret = sprintf(buf, "tmp121\n");
break;
+   case LM71_CHIP_LM71:
+   ret = sprintf(buf, "lm71\n");
+   break;
+   case LM74_CHIP_LM74:
+   ret = sprintf(buf, "lm74\n");
+   break;
default:
ret = -EINVAL;
}
@@ -139,7 +156,7 @@
struct lm70 *p_lm70;
int status;
 
-   /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+   /* signaling is SPI_MODE_0 */
if (spi->mode & (SPI_CPOL | SPI_CPHA))
return -EINVAL;
 
@@ -198,6 +215,8 @@
 static const struct spi_device_id lm70_ids[] = {
{ "lm70",   LM70_CHIP_LM70 },
{ "tmp121", LM70_CHIP_TMP121 },
+   { "lm71", LM70_CHIP_LM71 },
+   { "lm74", LM70_CHIP_LM74 },
{ },
 };
 MODULE_DEVICE_TABLE(spi, lm70_ids);
@@ -215,5 +234,5 @@
 module_spi_driver(lm70_driver);
 
 MODULE_AUTHOR("Kaiwan N Billimoria");
-MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
+MODULE_DESCRIPTION("NS LM70 and compatibles Linux driver");
 MODULE_LICENSE("GPL");
diff -u linux-3.5-vanilla/Documentation/hwmon/lm70 
linux-3.5/Documentation/hwmon/lm70
--- linux-3.5-vanilla/Documentation/hwmon/lm70  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/Documentation/hwmon/lm70  2012-08-25 00:37:15.0 +0200
@@ -6,6 +6,10 @@
 Datasheet: http://www.national.com/pf/LM/LM70.html
   * Texas Instruments TMP121/TMP123
 Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
+  * National Semiconductor LM71
+Datasheet: http://www.ti.com/product/LM71
+  * National Semiconductor LM74
+Datasheet: http://www.ti.com/product/LM74
 
 Author:
 Kaiwan N Billimoria 
@@ -31,9 +35,12 @@
 with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
 and its associated documentation.
 
-The TMP121/TMP123 are very similar; main difference is 13-bit temperature
+The LM74 and TMP121/TMP123 are very similar; main difference is 13-bit 
temperature
 data (0.0625 degrees celsius resolution).
 
+The LM71 is also very similar; main difference is 14-bit temperature
+data (0.03125 degrees celsius resolution).
+
 Thanks to
 -
 Jean Delvare  for mentoring the hwmon-side driver
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] hwmon/lm70: Adds support for LM71 and LM74

2012-09-05 Thread Christophe Leroy
Adding support for LM74 and LM71 chips

Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/hwmon/Kconfig linux-3.5/drivers/hwmon/Kconfig
--- linux-3.5-vanilla/drivers/hwmon/Kconfig 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/Kconfig 2012-08-25 00:44:05.0 +0200
@@ -530,12 +530,12 @@
  will be called lm63.
 
 config SENSORS_LM70
-   tristate "National Semiconductor LM70 / Texas Instruments TMP121"
+   tristate "National Semiconductor LM70 and compatibles"
depends on SPI_MASTER
help
  If you say yes here you get support for the National Semiconductor
- LM70 and Texas Instruments TMP121/TMP123 digital temperature
- sensor chips.
+ LM70, LM71, LM74 and Texas Instruments TMP121/TMP123 digital tempera-
+ ture sensor chips.
 
  This driver can also be built as a module.  If so, the module
  will be called lm70.
diff -u linux-3.5-vanilla/drivers/hwmon/lm70.c linux-3.5/drivers/hwmon/lm70.c
--- linux-3.5-vanilla/drivers/hwmon/lm70.c  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/lm70.c  2012-08-25 00:49:46.0 +0200
@@ -43,6 +43,8 @@
 
 #define LM70_CHIP_LM70 0   /* original NS LM70 */
 #define LM70_CHIP_TMP121   1   /* TI TMP121/TMP123 */
+#define LM70_CHIP_LM71 2   /* NS LM71 */
+#define LM70_CHIP_LM74 3   /* NS LM74 */
 
 struct lm70 {
struct device *hwmon_dev;
@@ -88,9 +90,13 @@
 * Celsius.
 * So it's equivalent to multiplying by 0.25 * 1000 = 250.
 *
-* TMP121/TMP123:
+* LM74 and TMP121/TMP123:
 * 13 bits of 2's complement data, discard LSB 3 bits,
 * resolution 0.0625 degrees celsius.
+*
+* LM71:
+* 14 bits of 2's complement data, discard LSB 2 bits,
+* resolution 0.0312 degrees celsius.
 */
switch (p_lm70->chip) {
case LM70_CHIP_LM70:
@@ -98,8 +104,13 @@
break;
 
case LM70_CHIP_TMP121:
+   case LM70_CHIP_LM74:
val = ((int)raw / 8) * 625 / 10;
break;
+
+   case LM70_CHIP_LM71:
+   val = ((int)raw / 4) * 3125 / 100;
+   break;
}
 
status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
@@ -123,6 +134,12 @@
case LM70_CHIP_TMP121:
ret = sprintf(buf, "tmp121\n");
break;
+   case LM70_CHIP_LM71:
+   ret = sprintf(buf, "lm71\n");
+   break;
+   case LM70_CHIP_LM74:
+   ret = sprintf(buf, "lm74\n");
+   break;
default:
ret = -EINVAL;
}
@@ -139,7 +156,7 @@
struct lm70 *p_lm70;
int status;
 
-   /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+   /* signaling is SPI_MODE_0 */
if (spi->mode & (SPI_CPOL | SPI_CPHA))
return -EINVAL;
 
@@ -198,6 +215,8 @@
 static const struct spi_device_id lm70_ids[] = {
{ "lm70",   LM70_CHIP_LM70 },
{ "tmp121", LM70_CHIP_TMP121 },
+   { "lm71",   LM70_CHIP_LM71 },
+   { "lm74",   LM70_CHIP_LM74 },
{ },
 };
 MODULE_DEVICE_TABLE(spi, lm70_ids);
@@ -215,5 +234,5 @@
 module_spi_driver(lm70_driver);
 
 MODULE_AUTHOR("Kaiwan N Billimoria");
-MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
+MODULE_DESCRIPTION("NS LM70 and compatibles Linux driver");
 MODULE_LICENSE("GPL");
diff -u linux-3.5-vanilla/Documentation/hwmon/lm70 
linux-3.5/Documentation/hwmon/lm70
--- linux-3.5-vanilla/Documentation/hwmon/lm70  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/Documentation/hwmon/lm70  2012-08-25 00:37:15.0 +0200
@@ -6,6 +6,10 @@
 Datasheet: http://www.national.com/pf/LM/LM70.html
   * Texas Instruments TMP121/TMP123
 Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
+  * National Semiconductor LM71
+Datasheet: http://www.ti.com/product/LM71
+  * National Semiconductor LM74
+Datasheet: http://www.ti.com/product/LM74
 
 Author:
 Kaiwan N Billimoria 
@@ -31,9 +35,12 @@
 with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
 and its associated documentation.
 
-The TMP121/TMP123 are very similar; main difference is 13-bit temperature
-data (0.0625 degrees celsius resolution).
+The LM74 and TMP121/TMP123 are very similar; main difference is 13-bit
+temperature data (0.0625 degrees celsius resolution).
 
+The LM71 is also very similar; main difference is 14-bit temperature
+data (0.03125 degrees celsius resolution).
+
 Thanks to
 -
 Jean Delvare  for mentoring the hwmon-side driver
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] lxt PHY: Support for the buggy LXT973 rev A2

2012-09-22 Thread Christophe Leroy
This patch adds proper handling of the buggy revision A2 of LXT973 phy, adding
precautions linked to ERRATA Item 4:

Revision A2 of LXT973 chip randomly returns the contents of the previous even
register when you read a odd register regularly

Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/net/phy/lxt.c linux-3.5/drivers/net/phy/lxt.c
--- linux-3.5-vanilla/drivers/net/phy/lxt.c 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/net/phy/lxt.c 2012-09-15 19:20:34.0 +0200
@@ -54,8 +54,12 @@
 #define MII_LXT971_ISR 19  /* Interrupt Status Register */
 
 /* register definitions for the 973 */
-#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
 #define PCR_FIBER_SELECT 1
+#define MII_LXT973_SFR 27  /* Special Function Register */
+
+#define PHYDEV_PRIV_FIBER  1
+#define PHYDEV_PRIV_REVA2  2
 
 MODULE_DESCRIPTION("Intel LXT PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -99,6 +103,9 @@
return err;
 }
 
+/* register definitions for the 973 */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define PCR_FIBER_SELECT 1
 
 static int lxt971_ack_interrupt(struct phy_device *phydev)
 {
@@ -122,9 +129,138 @@
return err;
 }
 
+/*
+ * A2 version of LXT973 chip has an ERRATA: it randomly return the contents
+ * of the previous even register when you read a odd register regularly
+ */
+
+static int lxt973a2_update_link(struct phy_device *phydev)
+{
+   int status;
+   int control;
+   int retry = 8; /* we try 8 times */
+
+   /* Do a fake read */
+   status = phy_read(phydev, MII_BMSR);
+
+   if (status < 0)
+   return status;
+
+   control = phy_read(phydev, MII_BMCR);
+   if (control < 0)
+   return control;
+
+   do {
+   /* Read link and autonegotiation status */
+   status = phy_read(phydev, MII_BMSR);
+   } while (status >= 0 && retry-- && status == control);
+
+   if (status < 0)
+   return status;
+
+   if ((status & BMSR_LSTATUS) == 0)
+   phydev->link = 0;
+   else
+   phydev->link = 1;
+
+   return 0;
+}
+
+int lxt973a2_read_status(struct phy_device *phydev)
+{
+   int adv;
+   int err;
+   int lpa;
+   int lpagb = 0;
+
+   /* Update the link, but return if there was an error */
+   err = lxt973a2_update_link(phydev);
+   if (err)
+   return err;
+
+   if (AUTONEG_ENABLE == phydev->autoneg) {
+   int retry = 1;
+
+   adv = phy_read(phydev, MII_ADVERTISE);
+
+   if (adv < 0)
+   return adv;
+
+   do {
+   lpa = phy_read(phydev, MII_LPA);
+
+   if (lpa < 0)
+   return lpa;
+
+   /* If both registers are equal, it is suspect but not
+   * impossible, hence a new try
+   */
+   } while (lpa == adv && retry--);
+
+   lpa &= adv;
+
+   phydev->speed = SPEED_10;
+   phydev->duplex = DUPLEX_HALF;
+   phydev->pause = phydev->asym_pause = 0;
+
+   if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+   phydev->speed = SPEED_1000;
+
+   if (lpagb & LPA_1000FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+   phydev->speed = SPEED_100;
+
+   if (lpa & LPA_100FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else
+   if (lpa & LPA_10FULL)
+   phydev->duplex = DUPLEX_FULL;
+
+   if (phydev->duplex == DUPLEX_FULL) {
+   phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+   phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+   }
+   } else {
+   int bmcr = phy_read(phydev, MII_BMCR);
+
+   if (bmcr < 0)
+   return bmcr;
+
+   if (bmcr & BMCR_FULLDPLX)
+   phydev->duplex = DUPLEX_FULL;
+   else
+   phydev->duplex = DUPLEX_HALF;
+
+   if (bmcr & BMCR_SPEED1000)
+   phydev->speed = SPEED_1000;
+   else if (bmcr & BMCR_SPEED100)
+   phydev->speed = SPEED_100;
+   else
+   phydev->speed = SPEED_10;
+
+   phydev->pause = phydev->asym_pause = 0;
+   }
+
+   return 0;
+}
+
+static int lxt973_read_status(struct p

[PATCH v2] Powerpc 8xx CPM_UART desynchronisation

2012-09-23 Thread Christophe Leroy
This patch fixes a desynchronisation problem with CPM UART driver on
Powerpc MPC8xx. The problem happens if data is received before the device
is open by the user application.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -417,6 +417,7 @@
clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR);
clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
}
+   cpm_uart_initbd(pinfo);
cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
}
/* Install interrupt handler. */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Powerpc 8xx CPM_UART too many interrupts

2012-09-23 Thread Christophe Leroy
Setting the fifo to only 1 byte generates one interrupt every 1ms at 9600 bauds.
This is too much. This patch reduces the threshold to speeds below 2400 bauds 
like in the 8250 UART driver.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -71,7 +71,7 @@
 
 /**/
 
-#define HW_BUF_SPD_THRESHOLD9600
+#define HW_BUF_SPD_THRESHOLD2400
 
 /*
  * Check, if transmit buffers are processed
@@ -505,7 +505,7 @@
pr_debug("CPM uart[%d]:set_termios\n", port->line);
 
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
-   if (baud <= HW_BUF_SPD_THRESHOLD ||
+   if (baud < HW_BUF_SPD_THRESHOLD ||
(pinfo->port.state && pinfo->port.state->port.tty->low_latency))
pinfo->rx_fifosize = 1;
else
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Powerpc 8xx CPM_UART maxidl should not depend on fifo size

2012-09-23 Thread Christophe Leroy
maxidl register was set to fifo size. There is no reason to set this
register to same value as fifo size. Setting it now to 0x10 by default
as in the UCC UART driver.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -799,7 +799,7 @@
cpm_set_scc_fcr(sup);
 
out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
-   out_be16(&sup->scc_maxidl, pinfo->rx_fifosize);
+   out_be16(&sup->scc_maxidl, 0x10);
out_be16(&sup->scc_brkcr, 1);
out_be16(&sup->scc_parec, 0);
out_be16(&sup->scc_frmec, 0);
@@ -873,7 +873,7 @@
 
/* Using idle character time requires some additional tuning.  */
out_be16(&up->smc_mrblr, pinfo->rx_fifosize);
-   out_be16(&up->smc_maxidl, pinfo->rx_fifosize);
+   out_be16(&up->smc_maxidl, 0x10);
out_be16(&up->smc_brklen, 0);
out_be16(&up->smc_brkec, 0);
out_be16(&up->smc_brkcr, 1);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Powerpc 8xx CPM_UART setting MAXIDL register proportionaly to baud rate

2012-09-23 Thread Christophe Leroy
MAXIDL is the timeout after which a receive buffer is closed when not full if
no more characters are received. We calculate it from the baudrate so that the
duration is always the same at standard rates: about 4ms. At 9600 bauds it gives
a timeout of 4 characters, which is the timeout on the 8250 UART.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -501,6 +501,7 @@
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
smc_t __iomem *smcp = pinfo->smcp;
scc_t __iomem *sccp = pinfo->sccp;
+   int maxidl;
 
pr_debug("CPM uart[%d]:set_termios\n", port->line);
 
@@ -511,6 +512,17 @@
else
pinfo->rx_fifosize = RX_BUF_SIZE;
 
+   /* MAXIDL is the timeout after which a receive buffer is closed
+* when not full if no more characters are received.
+* We calculate it from the baudrate so that the duration is
+* always the same at standard rates: about 4ms.
+*/
+   maxidl = baud / 2400;
+   if (maxidl < 1)
+   maxidl = 1;
+   if (maxidl > 0x10)
+   maxidl = 0x10;
+
/* Character length programmed into the mode register is the
 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
 * 1 or 2 stop bits, minus 1.
@@ -611,6 +623,7 @@
 * SMC/SCC receiver is disabled.
 */
out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize);
+   out_be16(&pinfo->smcup->smc_maxidl, maxidl);
 
/* Set the mode register.  We want to keep a copy of the
 * enables, because we want to put them back if they were
@@ -623,6 +636,7 @@
SMCMR_SM_UART | prev_mode);
} else {
out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, 
pinfo->rx_fifosize);
+   out_be16(&pinfo->sccup->scc_maxidl, maxidl);
out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
}
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4] lxt PHY: Support for the buggy LXT973 rev A2

2012-09-24 Thread Christophe Leroy
This patch adds proper handling of the buggy revision A2 of LXT973 phy, adding
precautions linked to ERRATA Item 4:

Revision A2 of LXT973 chip randomly returns the contents of the previous even
register when you read a odd register regularly

Signed-off-by: Christophe Leroy 

diff -u a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
--- a/drivers/net/phy/lxt.c 2012-09-23 03:08:48.0 +0200
+++ b/drivers/net/phy/lxt.c 2012-09-23 03:18:00.0 +0200
@@ -122,6 +122,123 @@
return err;
 }
 
+/*
+ * A2 version of LXT973 chip has an ERRATA: it randomly return the contents
+ * of the previous even register when you read a odd register regularly
+ */
+
+static int lxt973a2_update_link(struct phy_device *phydev)
+{
+   int status;
+   int control;
+   int retry = 8; /* we try 8 times */
+
+   /* Do a fake read */
+   status = phy_read(phydev, MII_BMSR);
+
+   if (status < 0)
+   return status;
+
+   control = phy_read(phydev, MII_BMCR);
+   if (control < 0)
+   return control;
+
+   do {
+   /* Read link and autonegotiation status */
+   status = phy_read(phydev, MII_BMSR);
+   } while (status >= 0 && retry-- && status == control);
+
+   if (status < 0)
+   return status;
+
+   if ((status & BMSR_LSTATUS) == 0)
+   phydev->link = 0;
+   else
+   phydev->link = 1;
+
+   return 0;
+}
+
+int lxt973a2_read_status(struct phy_device *phydev)
+{
+   int adv;
+   int err;
+   int lpa;
+   int lpagb = 0;
+
+   /* Update the link, but return if there was an error */
+   err = lxt973a2_update_link(phydev);
+   if (err)
+   return err;
+
+   if (AUTONEG_ENABLE == phydev->autoneg) {
+   int retry = 1;
+
+   adv = phy_read(phydev, MII_ADVERTISE);
+
+   if (adv < 0)
+   return adv;
+
+   do {
+   lpa = phy_read(phydev, MII_LPA);
+
+   if (lpa < 0)
+   return lpa;
+
+   /* If both registers are equal, it is suspect but not
+   * impossible, hence a new try
+   */
+   } while (lpa == adv && retry--);
+
+   lpa &= adv;
+
+   phydev->speed = SPEED_10;
+   phydev->duplex = DUPLEX_HALF;
+   phydev->pause = phydev->asym_pause = 0;
+
+   if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+   phydev->speed = SPEED_1000;
+
+   if (lpagb & LPA_1000FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+   phydev->speed = SPEED_100;
+
+   if (lpa & LPA_100FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else {
+   if (lpa & LPA_10FULL)
+   phydev->duplex = DUPLEX_FULL;
+   }
+
+   if (phydev->duplex == DUPLEX_FULL) {
+   phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+   phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+   }
+   } else {
+   int bmcr = phy_read(phydev, MII_BMCR);
+
+   if (bmcr < 0)
+   return bmcr;
+
+   if (bmcr & BMCR_FULLDPLX)
+   phydev->duplex = DUPLEX_FULL;
+   else
+   phydev->duplex = DUPLEX_HALF;
+
+   if (bmcr & BMCR_SPEED1000)
+   phydev->speed = SPEED_1000;
+   else if (bmcr & BMCR_SPEED100)
+   phydev->speed = SPEED_100;
+   else
+   phydev->speed = SPEED_10;
+
+   phydev->pause = phydev->asym_pause = 0;
+   }
+
+   return 0;
+}
+
 static int lxt973_probe(struct phy_device *phydev)
 {
int val = phy_read(phydev, MII_LXT973_PCR);
@@ -175,6 +292,16 @@
.driver = { .owner = THIS_MODULE,},
 }, {
.phy_id = 0x00137a10,
+   .name   = "LXT973-A2",
+   .phy_id_mask= 0x,
+   .features   = PHY_BASIC_FEATURES,
+   .flags  = 0,
+   .probe  = lxt973_probe,
+   .config_aneg= lxt973_config_aneg,
+   .read_status= lxt973a2_read_status,
+   .driver = { .owner = THIS_MODULE,},
+}, {
+   .phy_id = 0x00137a10,
.name   = "LXT973",
.phy_id_mask= 0xfff0,
.features   = PHY_BASIC_FEATURES,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc/mpc8xx: Clearer Oops message for Software Emulation Exception

2013-08-28 Thread Christophe Leroy
This patch modifies the Oops message in case of Software Emulation Exception.
The existing message is quite confusing because it refers to FPU Emulation
while most often the issue is due to either a non supported instruction
(not necessarily FPU related) or a stale instruction due to HW issues.
The new message tries to be more generic in order to make the user understand
that the Oops is due to something wrong with an instruction, not necessarily
due to an FPU instruction.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11-rc6/arch/powerpc/kernel/traps.c 
linux/arch/powerpc/kernel/traps.c
--- linux-3.11-rc6/arch/powerpc/kernel/traps.c  2013-08-25 15:20:33.0 
+0200
+++ linux/arch/powerpc/kernel/traps.c   2013-08-25 15:31:29.0 +0200
@@ -1476,7 +1476,8 @@
 
if (!user_mode(regs)) {
debugger(regs);
-   die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
+   die("Kernel Mode Unimplemented Instruction or SW FPU Emulation",
+   regs, SIGFPE);
}
 
 #ifdef CONFIG_MATH_EMULATION
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] IIO AD7923 iio_consumer support

2013-10-05 Thread Christophe Leroy
This patch adds support for iio_consumer to Analog Devices AD7923 ADC driver.

Signed-off-by: Christophe Leroy 
Verified-by: Patrick Vasseur 

diff -urN a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
--- a/drivers/iio/adc/ad7923.c  1970-01-01 01:00:00.0 +0100
+++ b/drivers/iio/adc/ad7923.c  2013-02-12 15:16:29.0 +0100
@@ -19,11 +19,15 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
+#define AD7923_NAME"ad7923"
+
 #define AD7923_WRITE_CR(1 << 11)   /* write control 
register */
 #define AD7923_RANGE   (1 << 1)/* range to REFin */
 #define AD7923_CODING  (1 << 0)/* coding is straight binary */
@@ -96,6 +100,7 @@
.storagebits = 16,  \
.endianness = IIO_BE,   \
},  \
+   .datasheet_name = #index,   \
}
 
 #define DECLARE_AD7923_CHANNELS(name, bits) \
@@ -195,6 +200,31 @@
return IRQ_HANDLED;
 }
 
+/* default maps used by iio consumer */
+static struct iio_map ad7923_default_iio_maps[] = {
+   {
+   .consumer_dev_name = AD7923_NAME,
+   .consumer_channel = "channel_0",
+   .adc_channel_label = "0",
+   },
+   {
+   .consumer_dev_name = AD7923_NAME,
+   .consumer_channel = "channel_1",
+   .adc_channel_label = "1",
+   },
+   {
+   .consumer_dev_name = AD7923_NAME,
+   .consumer_channel = "channel_2",
+   .adc_channel_label = "2",
+   },
+   {
+   .consumer_dev_name = AD7923_NAME,
+   .consumer_channel = "channel_3",
+   .adc_channel_label = "3",
+   },
+   { }
+};
+
 static int ad7923_scan_direct(struct ad7923_state *st, unsigned ch)
 {
int ret, cmd;
@@ -325,12 +355,18 @@
if (ret)
goto error_disable_reg;
 
-   ret = iio_device_register(indio_dev);
+   ret = iio_map_array_register(indio_dev, ad7923_default_iio_maps);
if (ret)
goto error_cleanup_ring;
 
+   ret = iio_device_register(indio_dev);
+   if (ret)
+   goto error_unmap;
+
return 0;
 
+error_unmap:
+   iio_map_array_unregister(indio_dev);
 error_cleanup_ring:
iio_triggered_buffer_cleanup(indio_dev);
 error_disable_reg:
@@ -349,6 +385,7 @@
struct ad7923_state *st = iio_priv(indio_dev);
 
iio_device_unregister(indio_dev);
+   iio_map_array_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
regulator_disable(st->reg);
regulator_put(st->reg);
@@ -368,7 +405,7 @@
 
 static struct spi_driver ad7923_driver = {
.driver = {
-   .name   = "ad7923",
+   .name   = AD7923_NAME,
.owner  = THIS_MODULE,
},
.probe  = ad7923_probe,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB

2013-09-17 Thread Christophe Leroy
Activating CONFIG_PIN_TLB is supposed to pin the IMMR and the first three
8Mbytes pages. But the setting of the MD_CTR was missing so as the index is
decremented every DTLB update, the pinning of the third 8Mbytes page was
overwriting the DTLB entry for IMMR. At the same time, the last entry written
being entry 31, next entries would possibly get overwritten after.
We are now starting from entry 31 and decrementing.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S 
linux-3.11/arch/powerpc/kernel/head_8xx.S
--- linux-3.11.org/arch/powerpc/kernel/head_8xx.S   2013-09-02 
22:46:10.0 +0200
+++ linux-3.11/arch/powerpc/kernel/head_8xx.S   2013-09-09 11:28:54.0 
+0200
@@ -796,8 +796,7 @@
 
 #ifdef CONFIG_PIN_TLB
lis r10, (MD_RSV4I | MD_RESETVAL)@h
-   ori r10, r10, 0x1c00
-   mr  r8, r10
+   ori r10, r10, 0x1f00
 #else
lis r10, MD_RESETVAL@h
 #endif
@@ -829,7 +828,7 @@
 * internal registers (among other things).
 */
 #ifdef CONFIG_PIN_TLB
-   addir10, r10, 0x0100
+   addir10, r10, -0x0100
mtspr   SPRN_MD_CTR, r10
 #endif
mfspr   r9, 638 /* Get current IMMR */
@@ -848,7 +847,7 @@
 #ifdef CONFIG_PIN_TLB
/* Map two more 8M kernel data pages.
*/
-   addir10, r10, 0x0100
+   addir10, r10, -0x0100
mtspr   SPRN_MD_CTR, r10
 
lis r8, KERNELBASE@h/* Create vaddr for TLB */
@@ -862,6 +861,9 @@
addis   r11, r11, 0x0080/* Add 8M */
mtspr   SPRN_MD_RPN, r11
 
+   addir10, r10, -0x0100
+   mtspr   SPRN_MD_CTR, r10
+
addis   r8, r8, 0x0080  /* Add 8M */
mtspr   SPRN_MD_EPN, r8
mtspr   SPRN_MD_TWC, r9
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc 8xx: Reverting commit e0908085fc2391c85b85fb814ae1df377c8e0dcb which has become useless

2013-09-11 Thread Christophe Leroy
The commit e0908085fc2391c85b85fb814ae1df377c8e0dcb is not needed anymore.
The issue was because dcbst wrongly sets the store bit when causing a DTLB
error, but this is now fixed by commit 0a2ab51ffb8dfdf51402dcfb446629648c96bc78
which handles the buggy dcbx instructions on data page faults on the 8xx.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/mm/pgtable.c 
linux-3.11/arch/powerpc/mm/pgtable.c
--- linux-3.11.org/arch/powerpc/mm/pgtable.c2013-09-02 22:46:10.0 
+0200
+++ linux-3.11/arch/powerpc/mm/pgtable.c2013-09-09 11:25:57.0 
+0200
@@ -32,8 +32,6 @@
 #include 
 #include 
 
-#include "mmu_decl.h"
-
 static inline int is_exec_fault(void)
 {
return current->thread.regs && TRAP(current->thread.regs) == 0x400;
@@ -72,7 +70,7 @@
  * support falls into the same category.
  */
 
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) 
||
@@ -81,17 +79,6 @@
if (!pg)
return pte;
if (!test_bit(PG_arch_1, &pg->flags)) {
-#ifdef CONFIG_8xx
-   /* On 8xx, cache control instructions (particularly
-* "dcbst" from flush_dcache_icache) fault as write
-* operation if there is an unpopulated TLB entry
-* for the address in question. To workaround that,
-* we invalidate the TLB here, thus avoiding dcbst
-* misbehaviour.
-*/
-   /* 8xx doesn't care about PID, size or ind args */
-   _tlbil_va(addr, 0, 0, 0);
-#endif /* CONFIG_8xx */
flush_dcache_icache_page(pg);
set_bit(PG_arch_1, &pg->flags);
}
@@ -111,7 +98,7 @@
  * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
  * instead we "filter out" the exec permission for non clean pages.
  */
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
struct page *pg;
 
@@ -193,7 +180,7 @@
 * this context might not have been activated yet when this
 * is called.
 */
-   pte = set_pte_filter(pte, addr);
+   pte = set_pte_filter(pte);
 
/* Perform the setting of the PTE */
__set_pte_at(mm, addr, ptep, pte, 0);
Only in linux-3.11/arch/powerpc/mm/: pgtable.c.orig
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB

2013-09-11 Thread Christophe Leroy
Activating CONFIG_PIN_TLB is supposed to pin the IMMR and the first three
8Mbytes pages. But the setting of the MD_CTR was missing so as the index is
decremented every DTLB update, the pinning of the third 8Mbytes page was
overwriting the DTLB entry for IMMR.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S 
linux-3.11/arch/powerpc/kernel/head_8xx.S
--- linux-3.11.org/arch/powerpc/kernel/head_8xx.S   2013-09-02 
22:46:10.0 +0200
+++ linux-3.11/arch/powerpc/kernel/head_8xx.S   2013-09-09 11:28:54.0 
+0200
@@ -862,6 +862,9 @@
addis   r11, r11, 0x0080/* Add 8M */
mtspr   SPRN_MD_RPN, r11
 
+   addir10, r10, 0x0100
+   mtspr   SPRN_MD_CTR, r10
+
addis   r8, r8, 0x0080  /* Add 8M */
mtspr   SPRN_MD_EPN, r8
mtspr   SPRN_MD_TWC, r9
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc 8xx: Reverting commit e0908085fc2391c85b85fb814ae1df377c8e0dcb which has become useless

2013-09-11 Thread Christophe Leroy
The commit e0908085fc2391c85b85fb814ae1df377c8e0dcb is not needed anymore.
The issue was because dcbst wrongly sets the store bit when causing a DTLB
error, but this is now fixed by commit 0a2ab51ffb8dfdf51402dcfb446629648c96bc78
which handles the buggy dcbx instructions on data page faults on the 8xx.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/mm/pgtable.c 
linux-3.11/arch/powerpc/mm/pgtable.c
--- linux-3.11.org/arch/powerpc/mm/pgtable.c2013-09-02 22:46:10.0 
+0200
+++ linux-3.11/arch/powerpc/mm/pgtable.c2013-09-09 11:25:57.0 
+0200
@@ -32,8 +32,6 @@
 #include 
 #include 
 
-#include "mmu_decl.h"
-
 static inline int is_exec_fault(void)
 {
return current->thread.regs && TRAP(current->thread.regs) == 0x400;
@@ -72,7 +70,7 @@
  * support falls into the same category.
  */
 
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) 
||
@@ -81,17 +79,6 @@
if (!pg)
return pte;
if (!test_bit(PG_arch_1, &pg->flags)) {
-#ifdef CONFIG_8xx
-   /* On 8xx, cache control instructions (particularly
-* "dcbst" from flush_dcache_icache) fault as write
-* operation if there is an unpopulated TLB entry
-* for the address in question. To workaround that,
-* we invalidate the TLB here, thus avoiding dcbst
-* misbehaviour.
-*/
-   /* 8xx doesn't care about PID, size or ind args */
-   _tlbil_va(addr, 0, 0, 0);
-#endif /* CONFIG_8xx */
flush_dcache_icache_page(pg);
set_bit(PG_arch_1, &pg->flags);
}
@@ -111,7 +98,7 @@
  * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
  * instead we "filter out" the exec permission for non clean pages.
  */
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
struct page *pg;
 
@@ -193,7 +180,7 @@
 * this context might not have been activated yet when this
 * is called.
 */
-   pte = set_pte_filter(pte, addr);
+   pte = set_pte_filter(pte);
 
/* Perform the setting of the PTE */
__set_pte_at(mm, addr, ptep, pte, 0);
Only in linux-3.11/arch/powerpc/mm/: pgtable.c.orig
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB

2013-09-12 Thread Christophe Leroy
This is a reorganisation of the setup of the TLB at kernel startup, in order
to handle the CONFIG_PIN_TLB case in accordance with chapter 8.10.3 of MPC866
and MPC885 reference manuals.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S 
linux-3.11/arch/powerpc/kernel/head_8xx.S
--- linux-3.11.org/arch/powerpc/kernel/head_8xx.S   2013-09-02 
22:46:10.0 +0200
+++ linux-3.11/arch/powerpc/kernel/head_8xx.S   2013-09-09 11:28:54.0 
+0200
@@ -785,27 +785,24 @@
  * these mappings is mapped by page tables.
  */
 initial_mmu:
-   tlbia   /* Invalidate all TLB entries */
-/* Always pin the first 8 MB ITLB to prevent ITLB
-   misses while mucking around with SRR0/SRR1 in asm
-*/
-   lis r8, MI_RSV4I@h
-   ori r8, r8, 0x1c00
-
+   lis r8, MI_RESETVAL@h
mtspr   SPRN_MI_CTR, r8 /* Set instruction MMU control */
 
-#ifdef CONFIG_PIN_TLB
-   lis r10, (MD_RSV4I | MD_RESETVAL)@h
-   ori r10, r10, 0x1c00
-   mr  r8, r10
-#else
lis r10, MD_RESETVAL@h
-#endif
 #ifndef CONFIG_8xx_COPYBACK
orisr10, r10, MD_WTDEF@h
 #endif
mtspr   SPRN_MD_CTR, r10/* Set data TLB control */
 
+   tlbia   /* Invalidate all TLB entries */
+
+   ori r8, r8, 0x1c00
+   mtspr   SPRN_MI_CTR, r8 /* Set instruction MMU control */
+#ifdef CONFIG_PIN_TLB
+   ori r10, r10, 0x1c00
+   mtspr   SPRN_MD_CTR, r10/* Set data TLB control */
+#endif
+
/* Now map the lower 8 Meg into the TLBs.  For this quick hack,
 * we can load the instruction and data TLB registers with the
 * same values.
@@ -825,6 +822,12 @@
mtspr   SPRN_MI_AP, r8
mtspr   SPRN_MD_AP, r8
 
+   /* Always pin the first 8 MB ITLB to prevent ITLB
+* misses while mucking around with SRR0/SRR1 in asm
+*/
+   lis r8, (MI_RSV4I | MI_RESETVAL)@h
+   mtspr   SPRN_MI_CTR, r8 /* Set instruction MMU control */
+
/* Map another 8 MByte at the IMMR to get the processor
 * internal registers (among other things).
 */
@@ -870,7 +873,15 @@
mtspr   SPRN_MD_TWC, r9
addis   r11, r11, 0x0080/* Add 8M */
mtspr   SPRN_MD_RPN, r11
+
+   lis r10, (MD_RSV4I | MD_RESETVAL)@h
+#else
+   lis r10, MD_RESETVAL@h
 #endif
+#ifndef CONFIG_8xx_COPYBACK
+   orisr10, r10, MD_WTDEF@h
+#endif
+   mtspr   SPRN_MD_CTR, r10/* Set data TLB control */
 
/* Since the cache is enabled according to the information we
 * just loaded into the TLB, invalidate and enable the caches here.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4] powerpc 8xx: Fixing issue with CONFIG_PIN_TLB

2013-09-24 Thread Christophe Leroy
Activating CONFIG_PIN_TLB is supposed to pin the IMMR and the first three
8Mbytes pages. But the setting of MD_CTR to a pinnable entry was missing before
the pinning of the third 8Mb page. As the index is decremented module 28
(MD_RSV4D is set) after every DTLB update, the third 8Mbytes page was
not pinned.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.11.org/arch/powerpc/kernel/head_8xx.S 
linux-3.11/arch/powerpc/kernel/head_8xx.S
--- linux-3.11.org/arch/powerpc/kernel/head_8xx.S   2013-09-02 
22:46:10.0 +0200
+++ linux-3.11/arch/powerpc/kernel/head_8xx.S   2013-09-09 11:28:54.0 
+0200
@@ -862,6 +862,9 @@
addis   r11, r11, 0x0080/* Add 8M */
mtspr   SPRN_MD_RPN, r11
 
+   addir10, r10, 0x0100
+   mtspr   SPRN_MD_CTR, r10
+
addis   r8, r8, 0x0080  /* Add 8M */
mtspr   SPRN_MD_EPN, r8
mtspr   SPRN_MD_TWC, r9
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] lxt PHY: Support for the buggy LXT973 rev A2

2012-09-10 Thread Christophe Leroy
This patch adds proper handling of the buggy revision A2 of LXT973 phy, adding
precautions linked to ERRATA Item 4:

Item 4: MDIO Interface and Repeated Polling
Problem: Repeated polling of odd-numbered registers via the MDIO interface
randomly returns the contents of the previous even register.
Implication: Managed applications may not obtain the correct register contents
when a particular register is monitored for device status.
Workaround: None.
Status: This erratum has been previously fixed (in rev A3)


Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/net/phy/lxt.c linux-3.5/drivers/net/phy/lxt.c
--- linux-3.5-vanilla/drivers/net/phy/lxt.c 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/net/phy/lxt.c 2012-09-07 18:08:54.0 +0200
@@ -7,6 +7,10 @@
  *
  * Copyright (c) 2004 Freescale Semiconductor, Inc.
  *
+ * Copyright (c) 2010 CSSI
+ *
+ * Added support for buggy LXT973 rev A2
+ *
  * 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
@@ -54,8 +58,12 @@
 #define MII_LXT971_ISR 19  /* Interrupt Status Register */
 
 /* register definitions for the 973 */
-#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
 #define PCR_FIBER_SELECT 1
+#define MII_LXT973_SFR 27  /* Special Function Register */
+
+#define PHYDEV_PRIV_FIBER  1
+#define PHYDEV_PRIV_REVA2  2
 
 MODULE_DESCRIPTION("Intel LXT PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -99,6 +107,9 @@
return err;
 }
 
+/* register definitions for the 973 */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define PCR_FIBER_SELECT 1
 
 static int lxt971_ack_interrupt(struct phy_device *phydev)
 {
@@ -122,9 +133,141 @@
return err;
 }
 
+/*
+ * ERRATA on LXT973
+ *
+ * Item 4: MDIO Interface and Repeated Polling
+ * Problem: Repeated polling of odd-numbered registers via the MDIO interface 
randomly returns the
+ * contents of the previous even register.
+ * Implication: Managed applications may not obtain the correct register 
contents when a particular
+ * register is monitored for device status.
+ * Workaround: None.
+ * Status: This erratum has been previously fixed (in rev A3)
+ *
+ */
+
+static int lxt973a2_update_link(struct phy_device *phydev)
+{
+   int status;
+   int control;
+   int retry = 8; /* we try 8 times */
+
+   /* Do a fake read */
+   status = phy_read(phydev, MII_BMSR);
+
+   if (status < 0)
+   return status;
+
+   control = phy_read(phydev, MII_BMCR);
+   if (control < 0)
+   return control;
+
+   do {
+   /* Read link and autonegotiation status */
+   status = phy_read(phydev, MII_BMSR);
+   } while (status>=0 && retry-- && status == control);
+
+   if (status < 0)
+   return status;
+
+   if ((status & BMSR_LSTATUS) == 0)
+   phydev->link = 0;
+   else
+   phydev->link = 1;
+
+   return 0;
+}
+
+int lxt973a2_read_status(struct phy_device *phydev)
+{
+   int adv;
+   int err;
+   int lpa;
+   int lpagb = 0;
+
+   /* Update the link, but return if there was an error */
+   err = lxt973a2_update_link(phydev);
+   if (err)
+   return err;
+
+   if (AUTONEG_ENABLE == phydev->autoneg) {
+   int retry = 1;
+   
+   adv = phy_read(phydev, MII_ADVERTISE);
+
+   if (adv < 0)
+   return adv;
+
+   do {
+   lpa = phy_read(phydev, MII_LPA);
+
+   if (lpa < 0)
+   return lpa;
+
+   /* If both registers are equal, it is suspect but not 
impossible, hence a new try */
+   } while (lpa == adv && retry--);
+
+   lpa &= adv;
+
+   phydev->speed = SPEED_10;
+   phydev->duplex = DUPLEX_HALF;
+   phydev->pause = phydev->asym_pause = 0;
+
+   if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+   phydev->speed = SPEED_1000;
+
+   if (lpagb & LPA_1000FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+   phydev->speed = SPEED_100;
+
+   if (lpa & LPA_100FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else
+   if (lpa & LPA_10FULL)
+   phydev->duplex = DUPLEX_FULL;
+
+   if (phydev->duplex

[PATCH] Erroneous double irq_eoi() on CPM IRQ in MPC8xx

2013-04-17 Thread Christophe Leroy
irq_eoi() is already called by generic_handle_irq() so 
it shall not be called a again

Signed-off-by: Christophe Leroy 

Index: linux/arch/powerpc/platforms/8xx/m8xx_setup.c
===
--- linux/arch/powerpc/platforms/8xx/m8xx_setup.c   (revision 4802)
+++ linux/arch/powerpc/platforms/8xx/m8xx_setup.c   (working copy)
@@ -218,19 +218,12 @@
 
 static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
 {
-   struct irq_chip *chip;
-   int cascade_irq;
+   struct irq_chip *chip = irq_desc_get_chip(desc);
+   int cascade_irq = cpm_get_irq());
 
-   if ((cascade_irq = cpm_get_irq()) >= 0) {
-   struct irq_desc *cdesc = irq_to_desc(cascade_irq);
-
+   if (cascade_irq >= 0)
generic_handle_irq(cascade_irq);
 
-   chip = irq_desc_get_chip(cdesc);
-   chip->irq_eoi(&cdesc->irq_data);
-   }
-
-   chip = irq_desc_get_chip(desc);
chip->irq_eoi(&desc->irq_data);
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] Erroneous double irq_eoi() on CPM IRQ in MPC8xx

2013-04-17 Thread Christophe Leroy
irq_eoi() is already called by generic_handle_irq() so 
it shall not be called a again

Signed-off-by: Christophe Leroy 

Index: linux/arch/powerpc/platforms/8xx/m8xx_setup.c
===
--- linux/arch/powerpc/platforms/8xx/m8xx_setup.c   (revision 4802)
+++ linux/arch/powerpc/platforms/8xx/m8xx_setup.c   (working copy)
@@ -218,19 +218,12 @@
 
 static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
 {
-   struct irq_chip *chip;
-   int cascade_irq;
+   struct irq_chip *chip = irq_desc_get_chip(desc);
+   int cascade_irq = cpm_get_irq();
 
-   if ((cascade_irq = cpm_get_irq()) >= 0) {
-   struct irq_desc *cdesc = irq_to_desc(cascade_irq);
-
+   if (cascade_irq >= 0)
generic_handle_irq(cascade_irq);
 
-   chip = irq_desc_get_chip(cdesc);
-   chip->irq_eoi(&cdesc->irq_data);
-   }
-
-   chip = irq_desc_get_chip(desc);
chip->irq_eoi(&desc->irq_data);
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Fix regression on spi-fsl-spi.c following modification on spi.c

2013-06-09 Thread Christophe Leroy
spi-fsl-spi.c made the assumption that t->bits_per_word and t->speed_hz were
set only when wanting to change the setting.
Since commit e6811d1d7a6a38ee637fe219c3b67dbfe17e8b3f, t->bits_per_word has
been set in all transfers, therefore the assumption made by the driver leads to
failure. This patch fixes the issue by comparing the t->new bits_per_word and
t->speed_hz with the previous one in order to determine if one of them changed.

Signed-off-by: Christophe Leroy 

--- linux-3.8.13/drivers/spi/spi-fsl-spi.c  2013-05-11 22:57:46.0 
+0200
+++ linux/drivers/spi/spi-fsl-spi.c 2013-06-09 00:13:30.0 +0200
@@ -476,11 +476,14 @@
unsigned int cs_change;
const int nsecs = 50;
int status;
+   u32 prev_speed_hz = 0;
+   u8 prev_bits_per_word = 0;
 
cs_change = 1;
status = 0;
list_for_each_entry(t, &m->transfers, transfer_list) {
-   if (t->bits_per_word || t->speed_hz) {
+   if (prev_bits_per_word != t->bits_per_word
+   || prev_speed_hz != t->speed_hz) {
/* Don't allow changes if CS is active */
status = -EINVAL;
 
@@ -488,6 +491,8 @@
status = fsl_spi_setup_transfer(spi, t);
if (status < 0)
break;
+   prev_bits_per_word = t->bits_per_word;
+   prev_speed_hz = t->speed_hz;
}
 
if (cs_change) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MAX7301 GPIO: Do not force SPI speed when using OF Platform

2013-03-22 Thread Christophe Leroy
The bit_per_word can be set in the OF Device tree, so no need to force it as 
with
the platform_data when using OF Platform

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -ur linux-3.8.4/drivers/gpio/gpio-max7301.c 
linux/drivers/gpio/gpio-max7301.c
--- linux-3.8.4/drivers/gpio/gpio-max7301.c 2013-03-20 21:11:19.0 
+0100
+++ linux/drivers/gpio/gpio-max7301.c   2013-03-16 10:27:30.0 +0100
@@ -56,7 +56,8 @@
int ret;
 
/* bits_per_word cannot be configured in platform data */
-   spi->bits_per_word = 16;
+   if (spi->dev.platform_data)
+   spi->bits_per_word = 16;
ret = spi_setup(spi);
if (ret < 0)
return ret;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] Adds support for Open Firmware in MAX730x GPIO Driver

2013-03-22 Thread christophe leroy

Le 22/03/2013 09:38, Linus Walleij a écrit :

On Tue, Mar 5, 2013 at 4:26 PM, Christophe Leroy
 wrote:


This patch allows the use of the MAX730x Driver on systems using
the Open Firmware platform format.
The bit_per_word can be set in the OF Device tree, so no need to force it as 
with
the platform_data.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

I tried applying this but it fails. Can you send based on e.g.
v3.9-rc3 or so?

Ok, part of it was already in 3.8
Made a new one based on 3.8.4
I checked it against 3.9-rc3, it is OK
NB: I changed the patch subject name

Regards
Christophe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] Adds support for Open Firmware in MAX730x GPIO Driver

2013-03-22 Thread christophe leroy

Le 22/03/2013 09:38, Linus Walleij a écrit :

On Tue, Mar 5, 2013 at 4:26 PM, Christophe Leroy
 wrote:


This patch allows the use of the MAX730x Driver on systems using
the Open Firmware platform format.
The bit_per_word can be set in the OF Device tree, so no need to force it as 
with
the platform_data.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

I tried applying this but it fails. Can you send based on e.g.
v3.9-rc3 or so?

Ok, part of it was already in 3.8
Made a new one based on 3.8.4
I checked it against 3.9-rc3, it is OK
NB: I changed the patch subject name

Regards
Christophe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] MAX7301 GPIO: Reverting "Do not force SPI speed when using OF Platform"

2013-08-19 Thread Christophe Leroy
This patch reverts commit 047b93a35961f7a6561e6f5dcb040738f822b892 which breaks
MAX7301 GPIO driver because that commit was dependant on a rejected patch that
was implementing selection of SPI speed from the Device Tree.

Signed-off-by: Christophe Leroy 

--- linux-3.11-rc6/drivers/gpio/gpio-max7301.c  2013-08-17 21:09:17.0 
+0200
+++ linux/drivers/gpio/gpio-max7301.c   2013-08-18 06:31:52.0 +0200
@@ -56,8 +56,7 @@
int ret;
 
/* bits_per_word cannot be configured in platform data */
-   if (spi->dev.platform_data)
-   spi->bits_per_word = 16;
+   spi->bits_per_word = 16;
ret = spi_setup(spi);
if (ret < 0)
return ret;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Adding proper request of GPIO used by cpm_uart driver

2013-08-21 Thread Christophe Leroy
cpm_uart serial driver uses GPIO for control signals. In order to be used
properly, GPIOs have to be reserved. Comment in gpiolib.c considers illegal
the use of GPIOs without requesting them. In addition, the direction of the
GPIO has to be set properly.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.8.13/drivers/tty/serial/cpm_uart/cpm_uart_core.c 
linux/drivers/tty/serial/cpm_uart/cpm_uart_core.c
--- linux-3.8.13/drivers/tty/serial/cpm_uart/cpm_uart_core.c2013-08-21 
05:34:03.0 +0200
+++ linux/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2013-08-21 
05:30:04.0 +0200
@@ -1213,8 +1213,32 @@
goto out_pram;
}
 
-   for (i = 0; i < NUM_GPIOS; i++)
-   pinfo->gpios[i] = of_get_gpio(np, i);
+   for (i = 0; i < NUM_GPIOS; i++) {
+   int gpio;
+
+   pinfo->gpios[i] = -1;
+
+   gpio = of_get_gpio(np, i);
+
+   if (gpio_is_valid(gpio)) {
+   ret = gpio_request(gpio, "cpm_uart");
+   if (ret) {
+   pr_err("can't request gpio #%d: %d\n", i, ret);
+   continue;
+   }
+   if (i == GPIO_RTS || i == GPIO_DTR)
+   ret = gpio_direction_output(gpio, 0);
+   else
+   ret = gpio_direction_input(gpio);
+   if (ret) {
+   pr_err("can't set direction for gpio #%d: %d\n",
+   i, ret);
+   gpio_free(gpio);
+   continue;
+   }
+   pinfo->gpios[i] = gpio;
+   }
+   }
 
 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
udbg_putc = NULL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] MAX7301 GPIO: Reverting "Do not force SPI speed when using OF Platform"

2013-08-24 Thread christophe leroy


Le 23/08/2013 19:47, Linus Walleij a écrit :

On Tue, Aug 20, 2013 at 8:29 AM, Christophe Leroy
 wrote:


This patch reverts commit 047b93a35961f7a6561e6f5dcb040738f822b892 which breaks
MAX7301 GPIO driver because that commit was dependant on a rejected patch that
was implementing selection of SPI speed from the Device Tree.

Signed-off-by: Christophe Leroy 

Patch applied with Roland's ACK.

But seriously, this is the kind of stuff that scares me a lot,
when developers merge dependent patches into two different
trees, that is just a recipe for chaos and me getting flamed
by other kernel maintainers.

There is *no* mention of this dependency in the other
commit.


I'm very sorry for this mishap. If I didn't mention it in the commit, 
this is because when I developped the change I submitted you a few 
months back, I was not aware of that other patch. It looks like it has 
been in my company's kernel tree for years, therefore in my mind it was 
a standard feature of the kernel. It looks like nobody had tried and 
submitted it for inclusion previously.
That's thanks to Roland that I discovered it was indeed not a standard 
feature, then I tried to submit that patch a week ago and it was 
rejected by Stephen Warren for good reason.

For me it is a lesson learnt, and I'll make sure it doesn't happen again.

Regards
Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] SPI: Set SPI bits per words in an OF DeviceTree SPI node

2013-08-07 Thread Christophe Leroy
This patch allows to set up the bits per word together with all other SPI
parameters in the SPI Node of the OF device tree

In the node, you then have to include the 'spi-bits' property.

Exemple:
fpga-loader@7 {
compatible = "cs,fpga-loader";
spi-max-frequency = <1000>;
reg = <7>;
spi-cs-high;
spi-bits = <16>;
    };

Signed-off-by: Christophe Leroy 

--- linux-3.8.13/drivers/spi/spi.c  2013-05-11 22:57:46.0 +0200
+++ linux/drivers/spi/spi.c 2013-08-06 18:19:30.0 +0200
@@ -870,6 +870,11 @@
if (of_find_property(nc, "spi-3wire", NULL))
spi->mode |= SPI_3WIRE;
 
+   /* Bits per word */
+   prop = of_get_property(nc, "spi-bits", &len);
+   if (prop && len >= sizeof(*prop))
+   spi->bits_per_word = prop[0];
+
/* Device speed */
prop = of_get_property(nc, "spi-max-frequency", &len);
if (!prop || len < sizeof(*prop)) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] Enhanced support for MPC8xx/8xxx watchdog

2013-08-07 Thread Christophe Leroy
This patch modifies the behaviour of the MPC8xx/8xxx watchdog. On the MPC8xx,
at 133Mhz, the maximum timeout of the watchdog timer is 1s, which means it must
be pinged twice a second. This is not in line with the Linux watchdog concept
which is based on a default watchdog timeout around 60s.
This patch introduces an intermediate layer between the CPU and the userspace.
The kernel pings the watchdog at the required frequency at the condition that
userspace tools refresh it regularly.
Existing parameter 'timeout' is renamed 'hw_timeout'.
The new parameter 'timeout' allows to set up the userspace timeout.
This patch also adds the WDIOC_SETTIMEOUT ioctl to the driver.

Signed-off-by: Christophe Leroy 

--- linux-3.8.13/drivers/watchdog/mpc8xxx_wdt.c 2013-05-11 22:57:46.0 
+0200
+++ linux/drivers/watchdog/mpc8xxx_wdt.c2013-08-08 02:12:15.0 
+0200
@@ -52,10 +52,18 @@
 static struct mpc8xxx_wdt __iomem *wd_base;
 static int mpc8xxx_wdt_init_late(void);
 
-static u16 timeout = 0x;
-module_param(timeout, ushort, 0);
+#define WD_TIMO 60 /* Default timeout = 60 seconds */
+
+static uint timeout = WD_TIMO;
+module_param(timeout, uint, 0);
 MODULE_PARM_DESC(timeout,
-   "Watchdog timeout in ticks. (0swcrr, tmp);
 
-   del_timer_sync(&wdt_timer);
+   wdt_auto = 0;
 
return nonseekable_open(inode, file);
 }
@@ -138,7 +163,8 @@
 static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
 {
if (!nowayout)
-   mpc8xxx_wdt_timer_ping(0);
+   wdt_auto = 1;
+
else
mpc8xxx_wdt_pr_warn("watchdog closed");
clear_bit(0, &wdt_is_open);
@@ -155,6 +181,7 @@
.firmware_version = 1,
.identity = "MPC8xxx",
};
+   int r;
 
switch (cmd) {
case WDIOC_GETSUPPORT:
@@ -163,10 +190,15 @@
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:
-   mpc8xxx_wdt_keepalive();
+   mpc8xxx_wdt_sw_keepalive();
return 0;
case WDIOC_GETTIMEOUT:
-   return put_user(timeout_sec, p);
+   return put_user(timeout, p);
+   case WDIOC_SETTIMEOUT:
+   r = get_user(timeout, p);
+   if (timeout > UINT_MAX / HZ)
+   timeout = UINT_MAX / HZ;
+   return r;
default:
return -ENOTTY;
}
@@ -215,21 +247,26 @@
ret = -ENOSYS;
goto err_unmap;
}
+   if (enabled)
+   hw_timeout = in_be32(&wd_base->swcrr) >> 16;
 
/* Calculate the timeout in seconds */
if (prescale)
-   timeout_sec = (timeout * wdt_type->prescaler) / freq;
+   hw_timeout_sec = (hw_timeout * wdt_type->prescaler) / freq;
else
-   timeout_sec = timeout / freq;
+   hw_timeout_sec = hw_timeout / freq;
 
+   /* Make sure the timeout is not too big */
+   if (timeout > UINT_MAX / HZ)
+   timeout = UINT_MAX / HZ;
 #ifdef MODULE
ret = mpc8xxx_wdt_init_late();
if (ret)
goto err_unmap;
 #endif
 
-   pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d 
seconds)\n",
-   reset ? "reset" : "interrupt", timeout, timeout_sec);
+   pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout = %d (%d 
seconds)\n",
+   reset ? "reset" : "interrupt", hw_timeout, hw_timeout_sec);
 
/*
 * If the watchdog was previously enabled or we're running on
@@ -273,6 +310,7 @@
.compatible = "fsl,mpc823-wdt",
.data = &(struct mpc8xxx_wdt_type) {
.prescaler = 0x800,
+   .hw_enabled = true,
},
},
{},
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] Adds support for Open Firmware in MAX730x GPIO Driver

2013-03-05 Thread Christophe Leroy
This patch allows the use of the MAX730x Driver on systems using
the Open Firmware platform format.
The bit_per_word can be set in the OF Device tree, so no need to force it as 
with
the platform_data.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.9/drivers/gpio/gpio-max7301.c 
linux/drivers/gpio/gpio-max7301.c
--- linux-3.7.9/drivers/gpio/gpio-max7301.c 2013-02-17 19:53:32.0 
+0100
+++ linux/drivers/gpio/gpio-max7301.c   2013-02-17 12:57:40.0 +0100
@@ -56,7 +56,8 @@
int ret;
 
/* bits_per_word cannot be configured in platform data */
-   spi->bits_per_word = 16;
+   if (spi->dev.platform_data)
+   spi->bits_per_word = 16;
ret = spi_setup(spi);
if (ret < 0)
return ret;
diff -ur linux-3.7.9/drivers/gpio/gpio-max730x.c 
linux/drivers/gpio/gpio-max730x.c
--- linux-3.7.9/drivers/gpio/gpio-max730x.c 2013-02-17 19:53:32.0 
+0100
+++ linux/drivers/gpio/gpio-max730x.c   2013-02-22 10:15:46.0 +0100
@@ -163,12 +163,13 @@
 int __devinit __max730x_probe(struct max7301 *ts)
 {
struct device *dev = ts->dev;
+   struct device_node *np = dev->of_node;
struct max7301_platform_data *pdata;
int i, ret;
 
pdata = dev->platform_data;
-   if (!pdata || !pdata->base) {
-   dev_err(dev, "incorrect or missing platform data\n");
+   if ((!pdata || !pdata->base) && !np) {
+   dev_err(dev, "No platform data nor Device Tree found\n");
return -EINVAL;
}
 
@@ -178,7 +179,6 @@
/* Power up the chip and disable IRQ output */
ts->write(dev, 0x04, 0x01);
 
-   ts->input_pullup_active = pdata->input_pullup_active;
ts->chip.label = dev->driver->name;
 
ts->chip.direction_input = max7301_direction_input;
@@ -186,7 +186,12 @@
ts->chip.direction_output = max7301_direction_output;
ts->chip.set = max7301_set;
 
-   ts->chip.base = pdata->base;
+   if (pdata) {
+   ts->input_pullup_active = pdata->input_pullup_active;
+   ts->chip.base = pdata->base;
+   } else {
+   ts->chip.base = -1;
+   }
ts->chip.ngpio = PIN_NUMBER;
ts->chip.can_sleep = 1;
ts->chip.dev = dev;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] hwmon/lm70: adding support for NS LM74 chip

2012-08-23 Thread Christophe Leroy
Hello,

This Patch adds support for the LM74 chip from National Semiconductor (NS) 
in the lm70 driver

Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/hwmon/Kconfig linux-3.5/drivers/hwmon/Kconfig
--- linux-3.5-vanilla/drivers/hwmon/Kconfig 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/Kconfig 2012-08-21 13:46:47.0 +0200
@@ -530,11 +530,11 @@
  will be called lm63.
 
 config SENSORS_LM70
-   tristate "National Semiconductor LM70 / Texas Instruments TMP121"
+   tristate "National Semiconductor LM70&LM74 / Texas Instruments TMP121"
depends on SPI_MASTER
help
  If you say yes here you get support for the National Semiconductor
- LM70 and Texas Instruments TMP121/TMP123 digital temperature
+ LM70 and LM74 and Texas Instruments TMP121/TMP123 digital temperature
  sensor chips.
 
  This driver can also be built as a module.  If so, the module
diff -u linux-3.5-vanilla/drivers/hwmon/lm70.c linux-3.5/drivers/hwmon/lm70.c
--- linux-3.5-vanilla/drivers/hwmon/lm70.c  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/hwmon/lm70.c  2012-08-21 13:46:31.0 +0200
@@ -3,11 +3,12 @@
  *
  * The LM70 is a temperature sensor chip from National Semiconductor (NS).
  * Copyright (C) 2006 Kaiwan N Billimoria 
+ * Copyright (C) 2012 Christophe Leroy 
  *
  * The LM70 communicates with a host processor via an SPI/Microwire Bus
  * interface. The complete datasheet is available at National's website
  * here:
- * http://www.national.com/pf/LM/LM70.html
+ * http://www.ti.com/product/LM70
  *
  * 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
@@ -43,6 +44,7 @@
 
 #define LM70_CHIP_LM70 0   /* original NS LM70 */
 #define LM70_CHIP_TMP121   1   /* TI TMP121/TMP123 */
+#define LM70_CHIP_LM74 2   /* original NS LM74 */
 
 struct lm70 {
struct device *hwmon_dev;
@@ -98,6 +100,7 @@
break;
 
case LM70_CHIP_TMP121:
+   case LM70_CHIP_LM74:
val = ((int)raw / 8) * 625 / 10;
break;
}
@@ -123,6 +126,9 @@
case LM70_CHIP_TMP121:
ret = sprintf(buf, "tmp121\n");
break;
+   case LM70_CHIP_LM74:
+   ret = sprintf(buf, "lm74\n");
+   break;
default:
ret = -EINVAL;
}
@@ -139,12 +145,13 @@
struct lm70 *p_lm70;
int status;
 
-   /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+   /* signaling is SPI_MODE_0 for LM70, LM74 and TMP121 */
if (spi->mode & (SPI_CPOL | SPI_CPHA))
return -EINVAL;
 
-   /* 3-wire link (shared SI/SO) for LM70 */
-   if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE))
+   /* 3-wire link (shared SI/SO) for LM70 and LM74 */
+   if ((chip == LM70_CHIP_LM70 || chip == LM70_CHIP_LM74)
+   && !(spi->mode & SPI_3WIRE))
return -EINVAL;
 
/* NOTE:  we assume 8-bit words, and convert to 16 bits manually */
@@ -202,6 +209,7 @@
 static const struct spi_device_id lm70_ids[] = {
{ "lm70",   LM70_CHIP_LM70 },
{ "tmp121", LM70_CHIP_TMP121 },
+   { "lm74",   LM70_CHIP_LM74 },
{ },
 };
 MODULE_DEVICE_TABLE(spi, lm70_ids);
@@ -219,5 +227,5 @@
 module_spi_driver(lm70_driver);
 
 MODULE_AUTHOR("Kaiwan N Billimoria");
-MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
+MODULE_DESCRIPTION("NS LM70 & LM74 / TI TMP121/TMP123 Linux driver");
 MODULE_LICENSE("GPL");
diff -u linux-3.5-vanilla/Documentation/hwmon/lm70 
linux-3.5/Documentation/hwmon/lm70
--- linux-3.5-vanilla/Documentation/hwmon/lm70  2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/Documentation/hwmon/lm70  2012-08-21 13:38:24.0 +0200
@@ -3,7 +3,9 @@
 
 Supported chips:
   * National Semiconductor LM70
-Datasheet: http://www.national.com/pf/LM/LM70.html
+Datasheet: http://www.ti.com/product/LM70
+  * National Semiconductor LM74
+Datasheet: http://www.ti.com/product/LM74
   * Texas Instruments TMP121/TMP123
 Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
 
@@ -31,9 +33,11 @@
 with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
 and its associated documentation.
 
-The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
-face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
-lution).
+The LM74 is very similar; main differences is 13-bit temperature data 
+(0.0625 degrees celsius resolution).
+
+The TMP121/TMP123 are very similar to the LM74; main difference is 4 wire
+SPI interface (read only).
 
 Thanks t

[PATCH] Powerpc 8xx CPM_UART delay in receive

2012-08-14 Thread Christophe Leroy
Hello,

I'm not sure who to address this Patch to either

It fixes a delay issue with CPM UART driver on Powerpc MPC8xx.
The problem is that with the actual code, the driver waits 32 IDLE patterns 
before returning the received data to the upper level. It means for instance 
about 1 second at 300 bauds.
This fix limits to one byte the waiting period.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -798,7 +799,7 @@
cpm_set_scc_fcr(sup);
 
out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize);
-   out_be16(&sup->scc_maxidl, pinfo->rx_fifosize);
+   out_be16(&sup->scc_maxidl, 1);
out_be16(&sup->scc_brkcr, 1);
out_be16(&sup->scc_parec, 0);
out_be16(&sup->scc_frmec, 0);
@@ -872,7 +873,7 @@
 
/* Using idle character time requires some additional tuning.  */
out_be16(&up->smc_mrblr, pinfo->rx_fifosize);
-   out_be16(&up->smc_maxidl, pinfo->rx_fifosize);
+   out_be16(&up->smc_maxidl, 1);
out_be16(&up->smc_brklen, 0);
out_be16(&up->smc_brkec, 0);
out_be16(&up->smc_brkcr, 1);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Powerpc 8xx CPM_UART desynchronisation

2012-08-14 Thread Christophe Leroy
Hello,

I'm not sure who to address this Patch to.

It fixes a desynchronisation problem with CPM UART driver on Powerpc MPC8xx.
The problem happens if data is received before the device is open by the user 
application.

Signed-off-by: Christophe Leroy 

--- linux-3.5-vanilla/drivers/tty/serial/cpm_uart/cpm_uart_core.c   
2012-07-21 22:58:29.0 +0200
+++ linux-3.5/drivers/tty/serial/cpm_uart/cpm_uart_core.c   2012-08-09 
17:38:37.0 +0200
@@ -417,6 +417,7 @@
clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR);
clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
}
+   cpm_uart_initbd(pinfo);
cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
}
/* Install interrupt handler. */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] lxt PHY: Support for the buggy LXT973 rev A2

2012-08-16 Thread Christophe Leroy
Hello,

This patch adds proper handling of the buggy revision A2 of LXT973 phy, adding 
precautions linked to ERRATA Item 4:

Item 4: MDIO Interface and Repeated Polling
Problem: Repeated polling of odd-numbered registers via the MDIO interface 
randomly returns the
contents of the previous even register.
Implication: Managed applications may not obtain the correct register contents 
when a particular
register is monitored for device status.
Workaround: None.
Status: This erratum has been previously fixed (in rev A3)


Signed-off-by: Christophe Leroy 

diff -u linux-3.5-vanilla/drivers/net/phy/lxt.c linux-3.5/drivers/net/phy/lxt.c
--- linux-3.5-vanilla/drivers/net/phy/lxt.c 2012-07-21 22:58:29.0 
+0200
+++ linux-3.5/drivers/net/phy/lxt.c 2012-04-21 17:08:21.0 +0200
@@ -7,6 +7,10 @@
  *
  * Copyright (c) 2004 Freescale Semiconductor, Inc.
  *
+ * Copyright (c) 2010 CSSI
+ *
+ * Added support for buggy LXT973 rev A2
+ *
  * 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
@@ -56,6 +60,10 @@
 /* register definitions for the 973 */
 #define MII_LXT973_PCR 16 /* Port Configuration Register */
 #define PCR_FIBER_SELECT 1
+#define MII_LXT973_SFR 27  /* Special Function Register */
+
+#define PHYDEV_PRIV_FIBER  1
+#define PHYDEV_PRIV_REVA2  2
 
 MODULE_DESCRIPTION("Intel LXT PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -99,6 +107,9 @@
return err;
 }
 
+/* register definitions for the 973 */
+#define MII_LXT973_PCR 16 /* Port Configuration Register */
+#define PCR_FIBER_SELECT 1
 
 static int lxt971_ack_interrupt(struct phy_device *phydev)
 {
@@ -122,9 +133,141 @@
return err;
 }
 
+/**
+ * ERRATA on LXT973
+ *
+ * Item 4: MDIO Interface and Repeated Polling
+ * Problem: Repeated polling of odd-numbered registers via the MDIO interface 
randomly returns the
+ * contents of the previous even register.
+ * Implication: Managed applications may not obtain the correct register 
contents when a particular
+ * register is monitored for device status.
+ * Workaround: None.
+ * Status: This erratum has been previously fixed (in rev A3)
+ *
+ */
+
+static int lxt973a2_update_link(struct phy_device *phydev)
+{
+   int status;
+   int control;
+   int retry = 8; /* we try 8 times */
+
+   /* Do a fake read */
+   status = phy_read(phydev, MII_BMSR);
+
+   if (status < 0)
+   return status;
+
+   control = phy_read(phydev, MII_BMCR);
+   if (control < 0)
+   return control;
+   
+   do {
+   /* Read link and autonegotiation status */
+   status = phy_read(phydev, MII_BMSR);
+   } while (status>=0 && retry-- && status == control);
+
+   if (status < 0)
+   return status;
+
+   if ((status & BMSR_LSTATUS) == 0)
+   phydev->link = 0;
+   else
+   phydev->link = 1;
+
+   return 0;
+}
+
+int lxt973a2_read_status(struct phy_device *phydev)
+{
+   int adv;
+   int err;
+   int lpa;
+   int lpagb = 0;
+
+   /* Update the link, but return if there
+* was an error */
+   err = lxt973a2_update_link(phydev);
+   if (err)
+   return err;
+
+   if (AUTONEG_ENABLE == phydev->autoneg) {
+   int retry = 1;
+   
+   adv = phy_read(phydev, MII_ADVERTISE);
+
+   if (adv < 0)
+   return adv;
+   
+   do {
+   lpa = phy_read(phydev, MII_LPA);
+
+   if (lpa < 0)
+   return lpa;
+
+   /* If both registers are equal, it is suspect but not 
impossible, hence a new try */
+   } while (lpa == adv && retry--);
+
+   lpa &= adv;
+
+   phydev->speed = SPEED_10;
+   phydev->duplex = DUPLEX_HALF;
+   phydev->pause = phydev->asym_pause = 0;
+
+   if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+   phydev->speed = SPEED_1000;
+
+   if (lpagb & LPA_1000FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+   phydev->speed = SPEED_100;
+   
+   if (lpa & LPA_100FULL)
+   phydev->duplex = DUPLEX_FULL;
+   } else
+   if (lpa & LPA_10FULL)
+   phydev->duplex = DUPLEX_FULL;
+
+   if (phydev->duplex == DUPLEX_FULL){
+   phydev->pause = lpa 

Re: [PATCH] IIO ADC support for AD7923

2013-01-19 Thread christophe leroy

Hi Lars,

Sorry to respond so late, I've been very busy lately.
Please see answers/questions below

Main point is that our driver is mainly copied and adapted from AD7298 
driver, and your comments are on things that we have not modified from 
AD7298, so what should we do really ?


We are a bit new comers in Kernel Development, so thanks for your help.

Christophe

Le 08/01/2013 11:27, Lars-Peter Clausen a écrit :

On 01/08/2013 09:42 AM, Christophe Leroy wrote:

This patch adds support for Analog Devices AD7923 ADC in the IIO Subsystem.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

Hi,

Thanks for the driver, looks pretty good. Some comments inline.

- Lars


diff -uN linux-3.7.1/drivers/staging/iio/adc/Kconfig 
linux/drivers/staging/iio/adc/Kconfig
--- linux-3.7.1/drivers/staging/iio/adc/Kconfig 2012-12-17 20:14:54.0 
+0100
+++ linux/drivers/staging/iio/adc/Kconfig   2012-12-13 19:52:10.0 
+0100

New IIO drivers should not be added to staging, unless there is a very good
reason. Since this driver does not have any major issues it should directly go
into drivers/iio/
Our driver is based on AD7298 driver, which is today in staging. Should 
we put ours in drivers/iio/ directly anyway ?


[...]


diff -uN linux-3.7.1/drivers/staging/iio/adc/ad7923.h 
linux/drivers/staging/iio/adc/ad7923.h
--- linux-3.7.1/drivers/staging/iio/adc/ad7923.h1970-01-01 
01:00:00.0 +0100
+++ linux/drivers/staging/iio/adc/ad7923.h  2013-01-05 17:53:53.0 
+0100
@@ -0,0 +1,72 @@
+/*
+ * AD7923 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc (from AD7298 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef IIO_ADC_AD7923_H_
+#define IIO_ADC_AD7923_H_
+
+#define AD7923_WRITE_CR(1 << 11) /* write control register */
+#define AD7923_RANGE   (1 << 1)  /* range to REFin */
+#define AD7923_CODING  (1 << 0)  /* coding is straight binary */
+#define AD7923_PM_MODE_AS  (1) /* auto shutdown */
+#define AD7923_PM_MODE_FS  (2) /* full shutdown */
+#define AD7923_PM_MODE_OPS (3) /* normal operation */
+#define AD7923_CHANNEL_0   (0) /* analog input 0 */
+#define AD7923_CHANNEL_1   (1) /* analog input 1 */
+#define AD7923_CHANNEL_2   (2) /* analog input 2 */
+#define AD7923_CHANNEL_3   (3) /* analog input 3 */
+#define AD7923_SEQUENCE_OFF(0) /* no sequence fonction */
+#define AD7923_SEQUENCE_PROTECT(2) /* no interrupt write 
cycle */
+#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
+
+#define AD7923_MAX_CHAN4
+
+#define AD7923_PM_MODE_WRITE(mode) (mode << 4)   /* write mode */
+#define AD7923_CHANNEL_WRITE(channel)  (channel << 6)/* write channel */
+#define AD7923_SEQUENCE_WRITE(sequence)(((sequence & 1) << 3) \
+   + ((sequence & 2) << 9))
+   /* write sequence fonction */
+/* left shift for CR : bit 11 transmit in first */
+#define AD7923_SHIFT_REGISTER  4
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define EXTRACT(val, dec, bits)((val >> dec) & ((1 << bits) - 
1))
+/* val = value, bits = number of bits of the original value */
+#define EXTRACT_PERCENT(val, bits) (((val + 1) * 100) >> bits)
+
+struct ad7923_state {
+   struct spi_device   *spi;
+   struct regulator*reg;
+   struct spi_transfer ring_xfer[6];
+   struct spi_transfer scan_single_xfer[2];
+   struct spi_message  ring_msg;
+   struct spi_message  scan_single_msg;
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   unsigned short  rx_buf[4] cacheline_aligned;
+   unsigned short  tx_buf[2];

both buffers should of type __be16

This part is copied unmodified from AD7298. Should we modify it ?



+};
+
+#ifdef CONFIG_IIO_BUFFER
+int ad7923_register_ring_funcs_and_init(struct iio_dev *indio_dev);
+void ad7923_ring_cleanup(struct iio_dev *indio_dev);
+int ad7923_update_scan_mode(struct iio_dev *indio_dev,
+   const unsigned long *active_scan_mask);
+#else /* CONFIG_IIO_BUFFER */
+static inline int
+ad7923_register_ring_funcs_and_init(struct iio_dev *indio_dev)
+{
+   return 0;
+}
+static inline void ad7923_ring_cleanup(struct iio_dev *indio_dev)
+{
+}
+#define ad7923_update_scan_mode NULL
+#endif /* CONFIG_IIO_BUFFER */
+#endif /* IIO_ADC_AD7923_H_ */
diff -uN linux-3.7.1/drivers/staging/iio/adc/ad7923_core.c 
linux/drivers/staging/iio/adc/ad7923_core.c
--- 

[PATCH v3] IIO ADC support for AD7923

2013-02-12 Thread Christophe Leroy
This patch adds support for Analog Devices AD7923 ADC in the IIO Subsystem.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -urN linux-next-e347c98/drivers/iio/adc/Kconfig 
linux-next-e347c98.new/drivers/iio/adc/Kconfig
--- linux-next-e347c98/drivers/iio/adc/Kconfig  2013-02-08 05:22:35.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/Kconfig  2013-02-12 
13:02:52.0 +0100
@@ -30,6 +30,18 @@
  To compile this driver as a module, choose M here: the
  module will be called ad7298.
 
+config AD7923
+   tristate "Analog Devices AD7923 ADC driver"
+   depends on SPI
+   select IIO_BUFFER
+   select IIO_TRIGGERED_BUFFER
+   help
+ Say yes here to build support for Analog Devices AD7923
+ 4 Channel ADC with temperature sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7923.
+
 config AD7791
tristate "Analog Devices AD7791 ADC driver"
depends on SPI
diff -urN linux-next-e347c98/drivers/iio/adc/Makefile 
linux-next-e347c98.new/drivers/iio/adc/Makefile
--- linux-next-e347c98/drivers/iio/adc/Makefile 2013-02-08 05:22:35.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/Makefile 2013-02-12 
13:03:02.0 +0100
@@ -5,6 +5,7 @@
 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AD7298) += ad7298.o
+obj-$(CONFIG_AD7923) += ad7923.o
 obj-$(CONFIG_AD7476) += ad7476.o
 obj-$(CONFIG_AD7791) += ad7791.o
 obj-$(CONFIG_AD7793) += ad7793.o
diff -urN linux-next-e347c98/drivers/iio/adc/ad7923.c 
linux-next-e347c98.new/drivers/iio/adc/ad7923.c
--- linux-next-e347c98/drivers/iio/adc/ad7923.c 1970-01-01 01:00:00.0 
+0100
+++ linux-next-e347c98.new/drivers/iio/adc/ad7923.c 2013-02-13 
02:03:38.0 +0100
@@ -0,0 +1,298 @@
+/*
+ * AD7923 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define AD7923_WRITE_CR(1 << 11)   /* write control 
register */
+#define AD7923_RANGE   (1 << 1)/* range to REFin */
+#define AD7923_CODING  (1 << 0)/* coding is straight binary */
+#define AD7923_PM_MODE_AS  (1) /* auto shutdown */
+#define AD7923_PM_MODE_FS  (2) /* full shutdown */
+#define AD7923_PM_MODE_OPS (3) /* normal operation */
+#define AD7923_CHANNEL_0   (0) /* analog input 0 */
+#define AD7923_CHANNEL_1   (1) /* analog input 1 */
+#define AD7923_CHANNEL_2   (2) /* analog input 2 */
+#define AD7923_CHANNEL_3   (3) /* analog input 3 */
+#define AD7923_SEQUENCE_OFF(0) /* no sequence fonction */
+#define AD7923_SEQUENCE_PROTECT(2) /* no interrupt write 
cycle */
+#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
+
+#define AD7923_MAX_CHAN4
+
+#define AD7923_PM_MODE_WRITE(mode) (mode << 4) /* write mode */
+#define AD7923_CHANNEL_WRITE(channel)  (channel << 6)  /* write channel */
+#define AD7923_SEQUENCE_WRITE(sequence)(((sequence & 1) << 3) \
+   + ((sequence & 2) << 9))
+   /* write sequence fonction */
+/* left shift for CR : bit 11 transmit in first */
+#define AD7923_SHIFT_REGISTER  4
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define EXTRACT(val, dec, bits)((val >> dec) & ((1 << bits) - 
1))
+
+struct ad7923_state {
+   struct spi_device   *spi;
+   struct spi_transfer ring_xfer[5];
+   struct spi_transfer scan_single_xfer[2];
+   struct spi_message  ring_msg;
+   struct spi_message  scan_single_msg;
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   __be16  rx_buf[4] cacheline_aligned;
+   __be16  tx_buf[4];
+};
+
+#define AD7923_V_CHAN(index)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = index,   \
+   .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
+  

[PATCH] Enhanced support for MPC8xx/8xxx watchdog

2013-02-13 Thread Christophe Leroy
This patch modifies the behaviour of the MPC8xx/8xxx watchdog. On the MPC8xx,
at 133Mhz, the maximum timeout of the watchdog timer is 1s, which means it must
be pinged twice a second. This is not in line with the Linux watchdog concept
which is based on a default watchdog timeout around 60s.
This patch introduces an intermediate layer between the CPU and the userspace.
The kernel pings the watchdog at the required frequency at the condition that
userspace tools refresh it regularly.
The new parameter 'heartbeat' allows to set up the userspace timeout.
The driver also implements the WDIOC_SETTIMEOUT ioctl.

Signed-off-by: Christophe Leroy 

diff -ur linux-3.7.7/drivers/watchdog/mpc8xxx_wdt.c 
linux/drivers/watchdog/mpc8xxx_wdt.c
--- linux-3.7.7/drivers/watchdog/mpc8xxx_wdt.c  2013-02-11 18:05:09.0 
+0100
+++ linux/drivers/watchdog/mpc8xxx_wdt.c2013-02-13 15:55:22.0 
+0100
@@ -52,10 +52,17 @@
 static struct mpc8xxx_wdt __iomem *wd_base;
 static int mpc8xxx_wdt_init_late(void);
 
+#define WD_TIMO 10 /* Default heartbeat = 10 seconds */
+
+static int heartbeat = WD_TIMO;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat,
+   "Watchdog SW heartbeat in seconds. (0 < heartbeat < 65536s, default="
+   __MODULE_STRING(WD_TIMO) "s)");
 static u16 timeout = 0x;
 module_param(timeout, ushort, 0);
 MODULE_PARM_DESC(timeout,
-   "Watchdog timeout in ticks. (0swcrr, tmp);
 
-   del_timer_sync(&wdt_timer);
+   wdt_auto = 0;
 
return nonseekable_open(inode, file);
 }
@@ -138,7 +158,8 @@
 static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
 {
if (!nowayout)
-   mpc8xxx_wdt_timer_ping(0);
+   wdt_auto = 1;
+
else
mpc8xxx_wdt_pr_warn("watchdog closed");
clear_bit(0, &wdt_is_open);
@@ -163,10 +184,12 @@
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:
-   mpc8xxx_wdt_keepalive();
+   mpc8xxx_wdt_sw_keepalive();
return 0;
case WDIOC_GETTIMEOUT:
-   return put_user(timeout_sec, p);
+   return put_user(heartbeat, p);
+   case WDIOC_SETTIMEOUT:
+   return get_user(heartbeat, p);
default:
return -ENOTTY;
}
@@ -215,6 +238,8 @@
ret = -ENOSYS;
goto err_unmap;
}
+   if (enabled)
+   timeout = in_be32(&wd_base->swcrr) >> 16;
 
/* Calculate the timeout in seconds */
if (prescale)
@@ -273,6 +298,7 @@
.compatible = "fsl,mpc823-wdt",
.data = &(struct mpc8xxx_wdt_type) {
.prescaler = 0x800,
+   .hw_enabled = true,
},
},
{},
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] IIO ADC support for AD7923

2013-01-08 Thread Christophe Leroy
This patch adds support for Analog Devices AD7923 ADC in the IIO Subsystem.

Signed-off-by: Patrick Vasseur 
Signed-off-by: Christophe Leroy 

diff -uN linux-3.7.1/drivers/staging/iio/adc/Kconfig 
linux/drivers/staging/iio/adc/Kconfig
--- linux-3.7.1/drivers/staging/iio/adc/Kconfig 2012-12-17 20:14:54.0 
+0100
+++ linux/drivers/staging/iio/adc/Kconfig   2012-12-13 19:52:10.0 
+0100
@@ -21,6 +21,17 @@
  To compile this driver as a module, choose M here: the
  module will be called ad7298.
 
+config AD7923
+   tristate "Analog Devices AD7923 ADC driver"
+   depends on SPI
+   select IIO_TRIGGERED_BUFFER if IIO_BUFFER
+   help
+ Say yes here to build support for Analog Devices AD7923
+ 4 Channel ADC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7923.
+
 config AD7606
tristate "Analog Devices AD7606 ADC driver"
depends on GPIOLIB
diff -uN linux-3.7.1/drivers/staging/iio/adc/Makefile 
linux/drivers/staging/iio/adc/Makefile
--- linux-3.7.1/drivers/staging/iio/adc/Makefile2012-12-17 
20:14:54.0 +0100
+++ linux/drivers/staging/iio/adc/Makefile  2012-12-13 19:52:10.0 
+0100
@@ -25,6 +25,10 @@
 ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o
 obj-$(CONFIG_AD7298) += ad7298.o
 
+ad7923-y := ad7923_core.o
+ad7923-$(CONFIG_IIO_BUFFER) += ad7923_ring.o
+obj-$(CONFIG_AD7923) += ad7923.o
+
 obj-$(CONFIG_AD7291) += ad7291.o
 obj-$(CONFIG_AD7780) += ad7780.o
 obj-$(CONFIG_AD7793) += ad7793.o
diff -uN linux-3.7.1/drivers/staging/iio/adc/ad7923.h 
linux/drivers/staging/iio/adc/ad7923.h
--- linux-3.7.1/drivers/staging/iio/adc/ad7923.h1970-01-01 
01:00:00.0 +0100
+++ linux/drivers/staging/iio/adc/ad7923.h  2013-01-05 17:53:53.0 
+0100
@@ -0,0 +1,72 @@
+/*
+ * AD7923 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc (from AD7298 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef IIO_ADC_AD7923_H_
+#define IIO_ADC_AD7923_H_
+
+#define AD7923_WRITE_CR(1 << 11)   /* write control 
register */
+#define AD7923_RANGE   (1 << 1)/* range to REFin */
+#define AD7923_CODING  (1 << 0)/* coding is straight binary */
+#define AD7923_PM_MODE_AS  (1) /* auto shutdown */
+#define AD7923_PM_MODE_FS  (2) /* full shutdown */
+#define AD7923_PM_MODE_OPS (3) /* normal operation */
+#define AD7923_CHANNEL_0   (0) /* analog input 0 */
+#define AD7923_CHANNEL_1   (1) /* analog input 1 */
+#define AD7923_CHANNEL_2   (2) /* analog input 2 */
+#define AD7923_CHANNEL_3   (3) /* analog input 3 */
+#define AD7923_SEQUENCE_OFF(0) /* no sequence fonction */
+#define AD7923_SEQUENCE_PROTECT(2) /* no interrupt write 
cycle */
+#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
+
+#define AD7923_MAX_CHAN4
+
+#define AD7923_PM_MODE_WRITE(mode) (mode << 4) /* write mode */
+#define AD7923_CHANNEL_WRITE(channel)  (channel << 6)  /* write channel */
+#define AD7923_SEQUENCE_WRITE(sequence)(((sequence & 1) << 3) \
+   + ((sequence & 2) << 9))
+   /* write sequence fonction */
+/* left shift for CR : bit 11 transmit in first */
+#define AD7923_SHIFT_REGISTER  4
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define EXTRACT(val, dec, bits)((val >> dec) & ((1 << bits) - 
1))
+/* val = value, bits = number of bits of the original value */
+#define EXTRACT_PERCENT(val, bits) (((val + 1) * 100) >> bits)
+
+struct ad7923_state {
+   struct spi_device   *spi;
+   struct regulator*reg;
+   struct spi_transfer ring_xfer[6];
+   struct spi_transfer scan_single_xfer[2];
+   struct spi_message  ring_msg;
+   struct spi_message  scan_single_msg;
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   unsigned short  rx_buf[4] cacheline_aligned;
+   unsigned short  tx_buf[2];
+};
+
+#ifdef CONFIG_IIO_BUFFER
+int ad7923_register_ring_funcs_and_init(struct iio_dev *indio_dev);
+void ad7923_ring_cleanup(struct iio_dev *indio_dev);
+int ad7923_update_scan_mode(struct iio_dev *indio_dev,
+   const unsigned long *active_scan_mask);
+#else /* CONFIG_IIO_BUFFER */
+static inline int
+ad7923_register_ring_funcs_and_init(struct iio_dev *indio_dev)
+{
+   return 0;
+}
+static inline void ad7923_ring_cleanup(struct iio_de

Re: [PATCH v2 2/3] powerpc: get hugetlbpage handling more generic

2016-09-19 Thread christophe leroy



Le 19/09/2016 à 07:45, Aneesh Kumar K.V a écrit :

Christophe Leroy  writes:


Today there are two implementations of hugetlbpages which are managed
by exclusive #ifdefs:
* FSL_BOOKE: several directory entries points to the same single hugepage
* BOOK3S: one upper level directory entry points to a table of hugepages

In preparation of implementation of hugepage support on the 8xx, we
need a mix of the two above solutions, because the 8xx needs both cases
depending on the size of pages:
* In 4k page size mode, each PGD entry covers a 4M bytes area. It means
that 2 PGD entries will be necessary to cover an 8M hugepage while a
single PGD entry will cover 8x 512k hugepages.
* In 16 page size mode, each PGD entry covers a 64M bytes area. It means
that 8x 8M hugepages will be covered by one PGD entry and 64x 512k
hugepages will be covers by one PGD entry.

This patch:
* removes #ifdefs in favor of if/else based on the range sizes
* merges the two huge_pte_alloc() functions as they are pretty similar
* merges the two hugetlbpage_init() functions as they are pretty similar

Signed-off-by: Christophe Leroy 
---
v2: This part is new and results from a split of last patch of v1 serie in
two parts

 arch/powerpc/mm/hugetlbpage.c | 189 +-
 1 file changed, 77 insertions(+), 112 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8a512b1..2119f00 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c


[...]




-#ifdef CONFIG_PPC_FSL_BOOK3E
 struct kmem_cache *hugepte_cache;
 static int __init hugetlbpage_init(void)
 {
int psize;

-   for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-   unsigned shift;
-
-   if (!mmu_psize_defs[psize].shift)
-   continue;
-
-   shift = mmu_psize_to_shift(psize);
-
-   /* Don't treat normal page sizes as huge... */
-   if (shift != PAGE_SHIFT)
-   if (add_huge_page_size(1ULL << shift) < 0)
-   continue;
-   }
-
-   /*
-* Create a kmem cache for hugeptes.  The bottom bits in the pte have
-* size information encoded in them, so align them to allow this
-*/
-   hugepte_cache =  kmem_cache_create("hugepte-cache", sizeof(pte_t),
-  HUGEPD_SHIFT_MASK + 1, 0, NULL);
-   if (hugepte_cache == NULL)
-   panic("%s: Unable to create kmem cache for hugeptes\n",
- __func__);
-
-   /* Default hpage size = 4M */
-   if (mmu_psize_defs[MMU_PAGE_4M].shift)
-   HPAGE_SHIFT = mmu_psize_defs[MMU_PAGE_4M].shift;
-   else
-   panic("%s: Unable to set default huge page size\n", __func__);
-
-
-   return 0;
-}
-#else
-static int __init hugetlbpage_init(void)
-{
-   int psize;
-
+#if !defined(CONFIG_PPC_FSL_BOOK3E)
if (!radix_enabled() && !mmu_has_feature(MMU_FTR_16M_PAGE))
return -ENODEV;
-
+#endif


Do we need that #if ? radix_enabled() should become 0 and that if
condition should be removed at compile time isn't it ? or are you
finding errors with that ?


Having radix_enabled() being 0, it becomes:

if (!mmu_has_feature(MMU_FTR_16M_PAGE))
return -ENODEV;

Which means hugepage will only be handled by CPUs having 16M pages. 
That's the issue.






for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
unsigned shift;
unsigned pdshift;
@@ -860,16 +807,31 @@ static int __init hugetlbpage_init(void)
 * if we have pdshift and shift value same, we don't
 * use pgt cache for hugepd.
 */
-   if (pdshift != shift) {
+   if (pdshift > shift) {
pgtable_cache_add(pdshift - shift, NULL);
if (!PGT_CACHE(pdshift - shift))
panic("hugetlbpage_init(): could not create "
  "pgtable cache for %d bit pagesize\n", 
shift);
+   } else if (!hugepte_cache) {
+   /*
+* Create a kmem cache for hugeptes.  The bottom bits in
+* the pte have size information encoded in them, so
+* align them to allow this
+*/
+   hugepte_cache = kmem_cache_create("hugepte-cache",
+ sizeof(pte_t),
+ HUGEPD_SHIFT_MASK + 1,
+ 0, NULL);
+   if (hugepte_cache == NULL)
+   panic("%s: Unable to create kmem cache "
+

Re: [PATCH v2 2/3] powerpc: get hugetlbpage handling more generic

2016-09-19 Thread christophe leroy



Le 19/09/2016 à 07:50, Aneesh Kumar K.V a écrit :


Christophe Leroy  writes:

+#else
+static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
+{
+   BUG();
+}
+
 #endif



I was expecting that BUG will get removed in the next patch. But I don't
see it in the next patch. Considering

@@ -475,11 +453,10 @@ static void free_hugepd_range(struct mmu_gather *tlb, 
hugepd_t *hpdp, int pdshif
for (i = 0; i < num_hugepd; i++, hpdp++)
hpdp->pd = 0;

-#ifdef CONFIG_PPC_FSL_BOOK3E
-   hugepd_free(tlb, hugepte);
-#else
-   pgtable_free_tlb(tlb, hugepte, pdshift - shift);
-#endif
+   if (shift >= pdshift)
+   hugepd_free(tlb, hugepte);
+   else
+   pgtable_free_tlb(tlb, hugepte, pdshift - shift);
 }

What is that I am missing ?



Previously, call to hugepd_free() was compiled only when #ifdef 
CONFIG_PPC_FSL_BOOK3E
Now, it is compiled at all time, but it should never be called if not 
CONFIG_PPC_FSL_BOOK3E because we always have shift < pdshift in that case.
Then the function needs to be defined anyway but should never be called. 
Should I just define it static inline {} ?


Christophe

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus



Re: [PATCH v2 1/3] powerpc: port 64 bits pgtable_cache to 32 bits

2016-09-19 Thread christophe leroy



Le 19/09/2016 à 07:22, Aneesh Kumar K.V a écrit :

Christophe Leroy  writes:


Today powerpc64 uses a set of pgtable_caches while powerpc32 uses
standard pages when using 4k pages and a single pgtable_cache
if using other size pages.

In preparation of implementing huge pages on the 8xx, this patch
replaces the specific powerpc32 handling by the 64 bits approach.

This is done by:
* moving 64 bits pgtable_cache_add() and pgtable_cache_init()
in a new file called init-common.c
* modifying pgtable_cache_init() to also handle the case
without PMD
* removing the 32 bits version of pgtable_cache_add() and
pgtable_cache_init()
* copying related header contents from 64 bits into both the
book3s/32 and nohash/32 header files

On the 8xx, the following cache sizes will be used:
* 4k pages mode:
- PGT_CACHE(10) for PGD
- PGT_CACHE(3) for 512k hugepage tables
* 16k pages mode:
- PGT_CACHE(6) for PGD
- PGT_CACHE(7) for 512k hugepage tables
- PGT_CACHE(3) for 8M hugepage tables

Signed-off-by: Christophe Leroy 
---
v2: in v1, hugepte_cache was wrongly replaced by PGT_CACHE(1).
This modification has been removed from v2.

 arch/powerpc/include/asm/book3s/32/pgalloc.h |  44 ++--
 arch/powerpc/include/asm/book3s/32/pgtable.h |  43 
 arch/powerpc/include/asm/book3s/64/pgtable.h |   3 -
 arch/powerpc/include/asm/nohash/32/pgalloc.h |  44 ++--
 arch/powerpc/include/asm/nohash/32/pgtable.h |  45 
 arch/powerpc/include/asm/nohash/64/pgtable.h |   2 -
 arch/powerpc/include/asm/pgtable.h   |   2 +
 arch/powerpc/mm/Makefile |   3 +-
 arch/powerpc/mm/init-common.c| 147 +++
 arch/powerpc/mm/init_64.c|  77 --
 arch/powerpc/mm/pgtable_32.c |  37 ---
 11 files changed, 273 insertions(+), 174 deletions(-)
 create mode 100644 arch/powerpc/mm/init-common.c

diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h 
b/arch/powerpc/include/asm/book3s/32/pgalloc.h
index 8e21bb4..d310546 100644
--- a/arch/powerpc/include/asm/book3s/32/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h
@@ -2,14 +2,42 @@
 #define _ASM_POWERPC_BOOK3S_32_PGALLOC_H

 #include 
+#include 

-/* For 32-bit, all levels of page tables are just drawn from get_free_page() */
-#define MAX_PGTABLE_INDEX_SIZE 0
+/*
+ * Functions that deal with pagetables that could be at any level of
+ * the table need to be passed an "index_size" so they know how to
+ * handle allocation.  For PTE pages (which are linked to a struct
+ * page for now, and drawn from the main get_free_pages() pool), the
+ * allocation size will be (2^index_size * sizeof(pointer)) and
+ * allocations are drawn from the kmem_cache in PGT_CACHE(index_size).
+ *
+ * The maximum index size needs to be big enough to allow any
+ * pagetable sizes we need, but small enough to fit in the low bits of
+ * any page table pointer.  In other words all pagetables, even tiny
+ * ones, must be aligned to allow at least enough low 0 bits to
+ * contain this value.  This value is also used as a mask, so it must
+ * be one less than a power of two.
+ */
+#define MAX_PGTABLE_INDEX_SIZE 0xf

 extern void __bad_pte(pmd_t *pmd);

-extern pgd_t *pgd_alloc(struct mm_struct *mm);
-extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+extern struct kmem_cache *pgtable_cache[];
+#define PGT_CACHE(shift) ({\
+   BUG_ON(!(shift));   \
+   pgtable_cache[(shift) - 1]; \
+   })
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+   return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL);
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+   kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
+}

 /*
  * We don't have any real pmd's, and this code never triggers because
@@ -68,8 +96,12 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t 
ptepage)

 static inline void pgtable_free(void *table, unsigned index_size)
 {
-   BUG_ON(index_size); /* 32-bit doesn't use this */
-   free_page((unsigned long)table);
+   if (!index_size) {
+   free_page((unsigned long)table);
+   } else {
+   BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
+   kmem_cache_free(PGT_CACHE(index_size), table);
+   }
 }

 #define check_pgt_cache()  do { } while (0)
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 6b8b2d5..f887499 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -8,6 +8,26 @@
 /* And here we include common definitions */
 #include 

+#define PTE_INDEX_SIZE PTE_SHIFT
+#define PMD_INDEX_SIZE 0
+#define PUD_INDEX_SIZE 0
+#define PGD_INDEX_SIZE (32 - PGDIR_SHIFT)
+
+#define PMD_CACHE_INDEXPMD_INDEX_SIZE
+
+#ifndef __ASSEMBLY__
+#define 

Re: [PATCH v2 2/3] powerpc: get hugetlbpage handling more generic

2016-09-19 Thread Christophe Leroy



Le 20/09/2016 à 04:28, Aneesh Kumar K.V a écrit :

christophe leroy  writes:


Le 19/09/2016 à 07:50, Aneesh Kumar K.V a écrit :


Christophe Leroy  writes:

+#else
+static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
+{
+   BUG();
+}
+
 #endif



I was expecting that BUG will get removed in the next patch. But I don't
see it in the next patch. Considering

@@ -475,11 +453,10 @@ static void free_hugepd_range(struct mmu_gather *tlb, 
hugepd_t *hpdp, int pdshif
for (i = 0; i < num_hugepd; i++, hpdp++)
hpdp->pd = 0;

-#ifdef CONFIG_PPC_FSL_BOOK3E
-   hugepd_free(tlb, hugepte);
-#else
-   pgtable_free_tlb(tlb, hugepte, pdshift - shift);
-#endif
+   if (shift >= pdshift)
+   hugepd_free(tlb, hugepte);
+   else
+   pgtable_free_tlb(tlb, hugepte, pdshift - shift);
 }

What is that I am missing ?



Previously, call to hugepd_free() was compiled only when #ifdef
CONFIG_PPC_FSL_BOOK3E
Now, it is compiled at all time, but it should never be called if not
CONFIG_PPC_FSL_BOOK3E because we always have shift < pdshift in that case.
Then the function needs to be defined anyway but should never be called.
Should I just define it static inline {} ?



For 8M with 4K mode, we have shift >= pdshift right ?



Yes, thats the reason why in the following patch we get. That way we get 
a real hugepd_free() also for the 8xx.


@@ -366,7 +373,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate)
 }
 #endif

-#ifdef CONFIG_PPC_FSL_BOOK3E
+#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx)
 #define HUGEPD_FREELIST_SIZE \
((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t))



Christophe


Re: [PATCH v2 2/3] powerpc: get hugetlbpage handling more generic

2016-09-20 Thread Christophe Leroy



Le 19/09/2016 à 07:45, Aneesh Kumar K.V a écrit :

Christophe Leroy  writes:


Today there are two implementations of hugetlbpages which are managed
by exclusive #ifdefs:
* FSL_BOOKE: several directory entries points to the same single hugepage
* BOOK3S: one upper level directory entry points to a table of hugepages

In preparation of implementation of hugepage support on the 8xx, we
need a mix of the two above solutions, because the 8xx needs both cases
depending on the size of pages:
* In 4k page size mode, each PGD entry covers a 4M bytes area. It means
that 2 PGD entries will be necessary to cover an 8M hugepage while a
single PGD entry will cover 8x 512k hugepages.
* In 16 page size mode, each PGD entry covers a 64M bytes area. It means
that 8x 8M hugepages will be covered by one PGD entry and 64x 512k
hugepages will be covers by one PGD entry.

This patch:
* removes #ifdefs in favor of if/else based on the range sizes
* merges the two huge_pte_alloc() functions as they are pretty similar
* merges the two hugetlbpage_init() functions as they are pretty similar

Signed-off-by: Christophe Leroy 
---
v2: This part is new and results from a split of last patch of v1 serie in
two parts

 arch/powerpc/mm/hugetlbpage.c | 189 +-
 1 file changed, 77 insertions(+), 112 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8a512b1..2119f00 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -64,14 +64,16 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
 {
struct kmem_cache *cachep;
pte_t *new;
-
-#ifdef CONFIG_PPC_FSL_BOOK3E
int i;
-   int num_hugepd = 1 << (pshift - pdshift);
-   cachep = hugepte_cache;
-#else
-   cachep = PGT_CACHE(pdshift - pshift);
-#endif
+   int num_hugepd;
+
+   if (pshift >= pdshift) {
+   cachep = hugepte_cache;
+   num_hugepd = 1 << (pshift - pdshift);
+   } else {
+   cachep = PGT_CACHE(pdshift - pshift);
+   num_hugepd = 1;
+   }


Is there a way to hint likely/unlikely branch based on the page size
selected at build time ?


Is that really worth it, won't it be negligeable compared to  other 
actions in that function (like for instance kmem_cache_zalloc()) ?

Can't we just trust GCC on that one ?

Christophe


[PATCH v3 0/3] powerpc: implementation of huge pages for 8xx

2016-09-21 Thread Christophe Leroy
This is v3 of patch serie is the implementation of support of
hugepages for the 8xx.
v1 of the serie was including some other fixes and
optimisations/reorganisations for the 8xx. Now the patch has been
split and this part only focuses on the implementation of
hugepages.

v2: the last patch has been split in two parts.
v3: Taking into account comments from aneesh

This patch serie applies on top of the patch serie named
"Optimisation on 8xx prior to hugepage implementation"


Christophe Leroy (3):
  powerpc: port 64 bits pgtable_cache to 32 bits
  powerpc: get hugetlbpage handling more generic
  powerpc/8xx: Implement support of hugepages

 arch/powerpc/include/asm/book3s/32/pgalloc.h |  44 +-
 arch/powerpc/include/asm/book3s/32/pgtable.h |  40 ++---
 arch/powerpc/include/asm/book3s/64/pgtable.h |   3 -
 arch/powerpc/include/asm/hugetlb.h   |  19 ++-
 arch/powerpc/include/asm/mmu-8xx.h   |  35 +
 arch/powerpc/include/asm/mmu.h   |  23 +--
 arch/powerpc/include/asm/nohash/32/pgalloc.h |  44 +-
 arch/powerpc/include/asm/nohash/32/pgtable.h |  42 +++---
 arch/powerpc/include/asm/nohash/32/pte-8xx.h |   1 +
 arch/powerpc/include/asm/nohash/64/pgtable.h |   2 -
 arch/powerpc/include/asm/nohash/pgtable.h|   4 +
 arch/powerpc/include/asm/pgtable.h   |   2 +
 arch/powerpc/include/asm/reg_8xx.h   |   2 +-
 arch/powerpc/kernel/head_8xx.S   | 119 ++-
 arch/powerpc/mm/Makefile |   3 +-
 arch/powerpc/mm/hugetlbpage.c| 211 ---
 arch/powerpc/mm/init-common.c| 107 ++
 arch/powerpc/mm/init_64.c|  77 --
 arch/powerpc/mm/pgtable_32.c |  37 -
 arch/powerpc/mm/tlb_nohash.c |  21 ++-
 arch/powerpc/platforms/8xx/Kconfig   |   1 +
 arch/powerpc/platforms/Kconfig.cputype   |   1 +
 22 files changed, 525 insertions(+), 313 deletions(-)
 create mode 100644 arch/powerpc/mm/init-common.c

-- 
2.1.0



[PATCH v3 1/3] powerpc: port 64 bits pgtable_cache to 32 bits

2016-09-21 Thread Christophe Leroy
Today powerpc64 uses a set of pgtable_caches while powerpc32 uses
standard pages when using 4k pages and a single pgtable_cache
if using other size pages.

In preparation of implementing huge pages on the 8xx, this patch
replaces the specific powerpc32 handling by the 64 bits approach.

This is done by:
* moving 64 bits pgtable_cache_add() and pgtable_cache_init()
in a new file called init-common.c
* modifying pgtable_cache_init() to also handle the case
without PMD
* removing the 32 bits version of pgtable_cache_add() and
pgtable_cache_init()
* copying related header contents from 64 bits into both the
book3s/32 and nohash/32 header files

On the 8xx, the following cache sizes will be used:
* 4k pages mode:
- PGT_CACHE(10) for PGD
- PGT_CACHE(3) for 512k hugepage tables
* 16k pages mode:
- PGT_CACHE(6) for PGD
- PGT_CACHE(7) for 512k hugepage tables
- PGT_CACHE(3) for 8M hugepage tables

Signed-off-by: Christophe Leroy 
---
v2: in v1, hugepte_cache was wrongly replaced by PGT_CACHE(1).
This modification has been removed from v2.

v3:
- Not adding anymore MIN_HUGEPTE_SHIFT to 32 bits headers as
this constant was last used on kernel 2.6.32.
- Fixed PMD_TABLE_SIZE and PUD_TABLE_SIZE
- Removed unneccessary includes from init-common.c

 arch/powerpc/include/asm/book3s/32/pgalloc.h |  44 +--
 arch/powerpc/include/asm/book3s/32/pgtable.h |  40 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h |   3 -
 arch/powerpc/include/asm/nohash/32/pgalloc.h |  44 +--
 arch/powerpc/include/asm/nohash/32/pgtable.h |  42 +--
 arch/powerpc/include/asm/nohash/64/pgtable.h |   2 -
 arch/powerpc/include/asm/pgtable.h   |   2 +
 arch/powerpc/mm/Makefile |   3 +-
 arch/powerpc/mm/init-common.c| 107 +++
 arch/powerpc/mm/init_64.c|  77 ---
 arch/powerpc/mm/pgtable_32.c |  37 -
 11 files changed, 227 insertions(+), 174 deletions(-)
 create mode 100644 arch/powerpc/mm/init-common.c

diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h 
b/arch/powerpc/include/asm/book3s/32/pgalloc.h
index 8e21bb4..d310546 100644
--- a/arch/powerpc/include/asm/book3s/32/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h
@@ -2,14 +2,42 @@
 #define _ASM_POWERPC_BOOK3S_32_PGALLOC_H
 
 #include 
+#include 
 
-/* For 32-bit, all levels of page tables are just drawn from get_free_page() */
-#define MAX_PGTABLE_INDEX_SIZE 0
+/*
+ * Functions that deal with pagetables that could be at any level of
+ * the table need to be passed an "index_size" so they know how to
+ * handle allocation.  For PTE pages (which are linked to a struct
+ * page for now, and drawn from the main get_free_pages() pool), the
+ * allocation size will be (2^index_size * sizeof(pointer)) and
+ * allocations are drawn from the kmem_cache in PGT_CACHE(index_size).
+ *
+ * The maximum index size needs to be big enough to allow any
+ * pagetable sizes we need, but small enough to fit in the low bits of
+ * any page table pointer.  In other words all pagetables, even tiny
+ * ones, must be aligned to allow at least enough low 0 bits to
+ * contain this value.  This value is also used as a mask, so it must
+ * be one less than a power of two.
+ */
+#define MAX_PGTABLE_INDEX_SIZE 0xf
 
 extern void __bad_pte(pmd_t *pmd);
 
-extern pgd_t *pgd_alloc(struct mm_struct *mm);
-extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+extern struct kmem_cache *pgtable_cache[];
+#define PGT_CACHE(shift) ({\
+   BUG_ON(!(shift));   \
+   pgtable_cache[(shift) - 1]; \
+   })
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+   return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL);
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+   kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
+}
 
 /*
  * We don't have any real pmd's, and this code never triggers because
@@ -68,8 +96,12 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t 
ptepage)
 
 static inline void pgtable_free(void *table, unsigned index_size)
 {
-   BUG_ON(index_size); /* 32-bit doesn't use this */
-   free_page((unsigned long)table);
+   if (!index_size) {
+   free_page((unsigned long)table);
+   } else {
+   BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
+   kmem_cache_free(PGT_CACHE(index_size), table);
+   }
 }
 
 #define check_pgt_cache()  do { } while (0)
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 6b8b2d5..388b052 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -8,6 +8,23 @@
 /* And here we include common definitions */
 #include 
 
+#define PTE_INDEX_SIZE PTE_SHIFT
+#define PMD_INDEX_SIZE 0
+#defi

[PATCH v3 2/3] powerpc: get hugetlbpage handling more generic

2016-09-21 Thread Christophe Leroy
Today there are two implementations of hugetlbpages which are managed
by exclusive #ifdefs:
* FSL_BOOKE: several directory entries points to the same single hugepage
* BOOK3S: one upper level directory entry points to a table of hugepages

In preparation of implementation of hugepage support on the 8xx, we
need a mix of the two above solutions, because the 8xx needs both cases
depending on the size of pages:
* In 4k page size mode, each PGD entry covers a 4M bytes area. It means
that 2 PGD entries will be necessary to cover an 8M hugepage while a
single PGD entry will cover 8x 512k hugepages.
* In 16 page size mode, each PGD entry covers a 64M bytes area. It means
that 8x 8M hugepages will be covered by one PGD entry and 64x 512k
hugepages will be covers by one PGD entry.

This patch:
* removes #ifdefs in favor of if/else based on the range sizes
* merges the two huge_pte_alloc() functions as they are pretty similar
* merges the two hugetlbpage_init() functions as they are pretty similar

Signed-off-by: Christophe Leroy 
---
v2: This part is new and results from a split of last patch of v1 serie in
two parts

v3:
- Only allocate hugepte_cache on FSL_BOOKE. Not needed on BOOK3S_64
- Removed the BUG in the unused hugepd_free(), made it
static inline {} instead.

 arch/powerpc/mm/hugetlbpage.c | 188 +-
 1 file changed, 76 insertions(+), 112 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a5d3ecd..a0d049a 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -64,14 +64,16 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
 {
struct kmem_cache *cachep;
pte_t *new;
-
-#ifdef CONFIG_PPC_FSL_BOOK3E
int i;
-   int num_hugepd = 1 << (pshift - pdshift);
-   cachep = hugepte_cache;
-#else
-   cachep = PGT_CACHE(pdshift - pshift);
-#endif
+   int num_hugepd;
+
+   if (pshift >= pdshift) {
+   cachep = hugepte_cache;
+   num_hugepd = 1 << (pshift - pdshift);
+   } else {
+   cachep = PGT_CACHE(pdshift - pshift);
+   num_hugepd = 1;
+   }
 
new = kmem_cache_zalloc(cachep, GFP_KERNEL);
 
@@ -89,7 +91,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
smp_wmb();
 
spin_lock(&mm->page_table_lock);
-#ifdef CONFIG_PPC_FSL_BOOK3E
+
/*
 * We have multiple higher-level entries that point to the same
 * actual pte location.  Fill in each as we go and backtrack on error.
@@ -100,8 +102,13 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
if (unlikely(!hugepd_none(*hpdp)))
break;
else
+#ifdef CONFIG_PPC_BOOK3S_64
+   hpdp->pd = __pa(new) |
+  (shift_to_mmu_psize(pshift) << 2);
+#else
/* We use the old format for PPC_FSL_BOOK3E */
hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
+#endif
}
/* If we bailed from the for loop early, an error occurred, clean up */
if (i < num_hugepd) {
@@ -109,17 +116,6 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
hpdp->pd = 0;
kmem_cache_free(cachep, new);
}
-#else
-   if (!hugepd_none(*hpdp))
-   kmem_cache_free(cachep, new);
-   else {
-#ifdef CONFIG_PPC_BOOK3S_64
-   hpdp->pd = __pa(new) | (shift_to_mmu_psize(pshift) << 2);
-#else
-   hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift;
-#endif
-   }
-#endif
spin_unlock(&mm->page_table_lock);
return 0;
 }
@@ -136,7 +132,6 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t 
*hpdp,
 #define HUGEPD_PUD_SHIFT PMD_SHIFT
 #endif
 
-#ifdef CONFIG_PPC_BOOK3S_64
 /*
  * At this point we do the placement change only for BOOK3S 64. This would
  * possibly work on other subarchs.
@@ -153,6 +148,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long 
addr, unsigned long sz
addr &= ~(sz-1);
pg = pgd_offset(mm, addr);
 
+#ifdef CONFIG_PPC_BOOK3S_64
if (pshift == PGDIR_SHIFT)
/* 16GB huge page */
return (pte_t *) pg;
@@ -178,32 +174,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long 
addr, unsigned long sz
hpdp = (hugepd_t *)pm;
}
}
-   if (!hpdp)
-   return NULL;
-
-   BUG_ON(!hugepd_none(*hpdp) && !hugepd_ok(*hpdp));
-
-   if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, 
pshift))
-   return NULL;
-
-   return hugepte_offset(*hpdp, addr, pdshift);
-}
-
 #else
-
-pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long 
sz)
-{

[PATCH v3 3/3] powerpc/8xx: Implement support of hugepages

2016-09-21 Thread Christophe Leroy
8xx uses a two level page table with two different linux page size
support (4k and 16k). 8xx also support two different hugepage sizes
512k and 8M. In order to support them on linux we define two different
page table layout.

The size of pages is in the PGD entry, using PS field (bits 28-29):
00 : Small pages (4k or 16k)
01 : 512k pages
10 : reserved
11 : 8M pages

For 512K hugepage size a pgd entry have the below format
[0101] . The hugepte table allocated will contain 8
entries pointing to 512K huge pte in 4k pages mode and 64 entries in
16k pages mode.

For 8M in 16k mode, a pgd entry have the below format
[1101] . The hugepte table allocated will contain 8
entries pointing to 8M huge pte.

For 8M in 4k mode, multiple pgd entries point to the same hugepte
address and pgd entry will have the below format
[1101]. The hugepte table allocated will only have one
entry.

For the time being, we do not support CPU15 ERRATA when HUGETLB is
selected

Signed-off-by: Christophe Leroy 
---
v2: This v1 was split in two parts. This part focuses on adding the
support on 8xx. It also fixes an error in TLBmiss handlers in the
case of 8M hugepages in 16k pages mode.

v3: No change

 arch/powerpc/include/asm/hugetlb.h   |  19 -
 arch/powerpc/include/asm/mmu-8xx.h   |  35 
 arch/powerpc/include/asm/mmu.h   |  23 +++---
 arch/powerpc/include/asm/nohash/32/pte-8xx.h |   1 +
 arch/powerpc/include/asm/nohash/pgtable.h|   4 +
 arch/powerpc/include/asm/reg_8xx.h   |   2 +-
 arch/powerpc/kernel/head_8xx.S   | 119 +--
 arch/powerpc/mm/hugetlbpage.c|  27 --
 arch/powerpc/mm/tlb_nohash.c |  21 -
 arch/powerpc/platforms/8xx/Kconfig   |   1 +
 arch/powerpc/platforms/Kconfig.cputype   |   1 +
 11 files changed, 224 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/include/asm/hugetlb.h 
b/arch/powerpc/include/asm/hugetlb.h
index c5517f4..3facdd4 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -51,12 +51,20 @@ static inline void __local_flush_hugetlb_page(struct 
vm_area_struct *vma,
 static inline pte_t *hugepd_page(hugepd_t hpd)
 {
BUG_ON(!hugepd_ok(hpd));
+#ifdef CONFIG_PPC_8xx
+   return (pte_t *)__va(hpd.pd & ~(_PMD_PAGE_MASK | _PMD_PRESENT_MASK));
+#else
return (pte_t *)((hpd.pd & ~HUGEPD_SHIFT_MASK) | PD_HUGE);
+#endif
 }
 
 static inline unsigned int hugepd_shift(hugepd_t hpd)
 {
+#ifdef CONFIG_PPC_8xx
+   return ((hpd.pd & _PMD_PAGE_MASK) >> 1) + 17;
+#else
return hpd.pd & HUGEPD_SHIFT_MASK;
+#endif
 }
 
 #endif /* CONFIG_PPC_BOOK3S_64 */
@@ -99,7 +107,15 @@ static inline int is_hugepage_only_range(struct mm_struct 
*mm,
 
 void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
pte_t pte);
+#ifdef CONFIG_PPC_8xx
+static inline void flush_hugetlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+   flush_tlb_page(vma, vmaddr);
+}
+#else
 void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+#endif
 
 void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
unsigned long end, unsigned long floor,
@@ -205,7 +221,8 @@ static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned 
long addr,
  * are reserved early in the boot process by memblock instead of via
  * the .dts as on IBM platforms.
  */
-#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PPC_FSL_BOOK3E)
+#if defined(CONFIG_HUGETLB_PAGE) && (defined(CONFIG_PPC_FSL_BOOK3E) || \
+defined(CONFIG_PPC_8xx))
 extern void __init reserve_hugetlb_gpages(void);
 #else
 static inline void reserve_hugetlb_gpages(void)
diff --git a/arch/powerpc/include/asm/mmu-8xx.h 
b/arch/powerpc/include/asm/mmu-8xx.h
index 3e0e492..798b5bf 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -172,6 +172,41 @@ typedef struct {
 
 #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff8)
 #define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
+
+/* Page size definitions, common between 32 and 64-bit
+ *
+ *shift : is the "PAGE_SHIFT" value for that page size
+ *penc  : is the pte encoding mask
+ *
+ */
+struct mmu_psize_def {
+   unsigned intshift;  /* number of bits */
+   unsigned intenc;/* PTE encoding */
+   unsigned intind;/* Corresponding indirect page size shift */
+   unsigned intflags;
+#define MMU_PAGE_SIZE_DIRECT   0x1 /* Supported as a direct size */
+#define MMU_PAGE_SIZE_INDIRECT 0x2 /* Supported as an indirect size */
+};
+
+extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+
+static inline int shift_to_mmu_psize(unsigned int shift)
+{
+   int psize;
+
+   for (psize = 0; psize < MMU_PAGE_COUNT; ++psize)
+   if (mmu_psize_defs[psiz

[PATCH] powerpc/64: get rid of MIN_HUGEPTE_SHIFT

2016-09-21 Thread Christophe Leroy
MIN_HUGEPTE_SHIFT hasn't been used since commit d1837cba5d5d5
("powerpc/mm: Cleanup initialization of hugepages on powerpc")

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/64/hash-4k.h | 3 ---
 arch/powerpc/include/asm/book3s/64/hash-64k.h| 3 ---
 arch/powerpc/include/asm/nohash/64/pgtable-4k.h  | 3 ---
 arch/powerpc/include/asm/nohash/64/pgtable-64k.h | 3 ---
 4 files changed, 12 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h 
b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index 1af837c..1c64bc6 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -16,9 +16,6 @@
 #define H_PUD_TABLE_SIZE   (sizeof(pud_t) << H_PUD_INDEX_SIZE)
 #define H_PGD_TABLE_SIZE   (sizeof(pgd_t) << H_PGD_INDEX_SIZE)
 
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT  PMD_SHIFT
-
 /* PTE flags to conserve for HPTE identification */
 #define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \
 H_PAGE_F_SECOND | H_PAGE_F_GIX)
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h 
b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index 5aae4f5..f3dd21e 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -6,9 +6,6 @@
 #define H_PUD_INDEX_SIZE  5
 #define H_PGD_INDEX_SIZE  12
 
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT  PAGE_SHIFT
-
 #define H_PAGE_COMBO   0x1000 /* this is a combo 4k page */
 #define H_PAGE_4K_PFN  0x2000 /* PFN is for a single 4k page */
 /*
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h 
b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
index fc7d517..d0db987 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
@@ -27,9 +27,6 @@
 #define PMD_SIZE   (1UL << PMD_SHIFT)
 #define PMD_MASK   (~(PMD_SIZE-1))
 
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT  PMD_SHIFT
-
 /* PUD_SHIFT determines what a third-level page table entry can map */
 #define PUD_SHIFT  (PMD_SHIFT + PMD_INDEX_SIZE)
 #define PUD_SIZE   (1UL << PUD_SHIFT)
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h 
b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h
index 9083245..55b28ef 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h
@@ -31,9 +31,6 @@
 #define PTRS_PER_PMD   (1 << PMD_INDEX_SIZE)
 #define PTRS_PER_PGD   (1 << PGD_INDEX_SIZE)
 
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT  PAGE_SHIFT
-
 /* PMD_SHIFT determines what a second-level page table entry can map */
 #define PMD_SHIFT  (PAGE_SHIFT + PTE_INDEX_SIZE)
 #define PMD_SIZE   (1UL << PMD_SHIFT)
-- 
2.1.0



[PATCH] powerpc/32: fix csum_partial_copy_generic()

2016-08-01 Thread Christophe Leroy
commit 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()") introduced a bug when destination
address is odd and initial csum is not null

In that (rare) case the initial csum value has to be rotated one byte
as well as the resulting value is

Fixes: 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()")
Cc: sta...@vger.kernel.org

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/lib/checksum_32.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index d90870a..ad0870a 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -127,7 +127,8 @@ _GLOBAL(csum_partial_copy_generic)
stw r7,12(r1)
stw r8,8(r1)
 
-   andi.   r0,r4,1 /* is destination address even ? */
+   rlwinm  r0,r4,3,0x8 /* is destination address even ? */
+   rlwnm   r6,r6,r0,0,31   /* swap bytes for odd destination */
cmplwi  cr7,r0,0
addic   r12,r6,0
addir6,r4,-4
-- 
2.1.0



Re: [PATCH] powerpc/32: fix csum_partial_copy_generic()

2016-08-01 Thread Christophe Leroy



Le 01/08/2016 à 15:15, Segher Boessenkool a écrit :

On Mon, Aug 01, 2016 at 02:56:05PM +0200, Christophe Leroy wrote:

--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -127,7 +127,8 @@ _GLOBAL(csum_partial_copy_generic)
stw r7,12(r1)
stw r8,8(r1)

-   andi.   r0,r4,1 /* is destination address even ? */
+   rlwinm  r0,r4,3,0x8 /* is destination address even ? */
+   rlwnm   r6,r6,r0,0,31   /* swap bytes for odd destination */
cmplwi  cr7,r0,0
addic   r12,r6,0
addir6,r4,-4


That does not "swap bytes"; it shifts the word up by 8 bits, instead.
That may or may not do what is intended.



Indeed it does what is intended, similar to what is done at the end of 
the function:


...
beqlr+  cr7
rlwinm  r3,r3,8,0,31/* swap bytes for odd destination */
blr

Should I fix the (both) comment(s) ?

Christophe


Re: [PATCH] powerpc/8xx: add system_reset_exception

2016-09-06 Thread Christophe Leroy



Le 07/09/2016 à 00:40, Scott Wood a écrit :

On Mon, 2016-09-05 at 08:42 +0200, Christophe Leroy wrote:

When the watchdog is in NMI mode, the system reset interrupt is
generated when the watchdog counter expires.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/head_8xx.S | 2 +-
 arch/powerpc/kernel/traps.c| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 43ddaae..f7b8007 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -227,7 +227,7 @@ i##n:   
\
  ret_from_except)

 /* System reset */
-   EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+   EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)


Does this do anything useful beyond what unknown_exception does?  Do you plan
to have a ppc_md.system_reset_exception callback?



Yes that's the plan, having a platform specific callback to take 
emergency actions in order to speed up systemwise recovery, then restart 
the board.


In addition, unknown_exception doesn't show you that the exception comes 
from the NMI watchdog.


Christophe


Re: [PATCH v2] powerpc/32: fix csum_partial_copy_generic()

2016-08-05 Thread Christophe Leroy



Le 05/08/2016 à 08:57, Michael Ellerman a écrit :

Alessio Igor Bogani  writes:

On 4 August 2016 at 05:53, Scott Wood  wrote:

On Tue, 2016-08-02 at 10:07 +0200, Christophe Leroy wrote:

commit 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()") introduced a bug when destination
address is odd and initial csum is not null

In that (rare) case the initial csum value has to be rotated one byte
as well as the resulting value is

This patch also fixes related comments

Fixes: 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()")
Cc: sta...@vger.kernel.org

Signed-off-by: Christophe Leroy 
---
  v2: updated comments as suggested by Segher

  arch/powerpc/lib/checksum_32.S | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

Alessio, can you confirm whether this fixes the problem you reported?

No unfortunately.

Thanks for testing.

I've dropped the patch for now, send me a new one that works.




The purpose of this patch was not to address Alessio's issue, but to fix 
a huge issue on checksum calculation which induces breakdown of TCP 
connections.


I think it is worth commiting it upstream and on impacted stable 
releases, allthought we don't have yet identified the issue Alessio's has.


Christophe


[PATCH] powerpc/40x: Clear MSR_DR in one insn instead of two

2016-08-05 Thread Christophe Leroy
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/misc_32.S | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index d9c912b..e025230 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -243,8 +243,7 @@ _GLOBAL(_nmask_and_or_msr)
  */
 _GLOBAL(real_readb)
mfmsr   r7
-   ori r0,r7,MSR_DR
-   xorir0,r0,MSR_DR
+   rlwinm  r0,r7,0,~MSR_DR
sync
mtmsr   r0
sync
@@ -261,8 +260,7 @@ _GLOBAL(real_readb)
  */
 _GLOBAL(real_writeb)
mfmsr   r7
-   ori r0,r7,MSR_DR
-   xorir0,r0,MSR_DR
+   rlwinm  r0,r7,0,~MSR_DR
sync
mtmsr   r0
sync
-- 
2.1.0



[PATCH] powerpc/32: Remove CLR_TOP32

2016-08-05 Thread Christophe Leroy
CLR_TOP32() is defined as blank. Last useful instance of CLR_TOP32()
was removed by commit 40ef8cbc6d360 ("powerpc: Get 64-bit configs to
compile with ARCH=powerpc")

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/ppc_asm.h | 1 -
 arch/powerpc/kernel/entry_32.S | 1 -
 arch/powerpc/kernel/head_32.S  | 3 ---
 arch/powerpc/kernel/head_8xx.S | 1 -
 4 files changed, 6 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc_asm.h 
b/arch/powerpc/include/asm/ppc_asm.h
index d5d5b5e..bcd891f 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -527,7 +527,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #endif
 #define MTMSRD(r)  mtmsr   r
 #define MTMSR_EERI(reg)mtmsr   reg
-#define CLR_TOP32(r)
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 9899032..83428a2 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -654,7 +654,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
 #endif /* CONFIG_SMP */
 
tophys(r0,r4)
-   CLR_TOP32(r0)
mtspr   SPRN_SPRG_THREAD,r0 /* Update current THREAD phys addr */
lwz r1,KSP(r4)  /* Load new stack pointer */
 
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index dc0488b..a3f821e 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -266,7 +266,6 @@ __secondary_hold_acknowledge:
 
 
 #define EXCEPTION_PROLOG_2 \
-   CLR_TOP32(r11); \
stw r10,_CCR(r11);  /* save registers */ \
stw r12,GPR12(r11); \
stw r9,GPR9(r11);   \
@@ -862,7 +861,6 @@ __secondary_start:
/* ptr to phys current thread */
tophys(r4,r2)
addir4,r4,THREAD/* phys address of our thread_struct */
-   CLR_TOP32(r4)
mtspr   SPRN_SPRG_THREAD,r4
li  r3,0
mtspr   SPRN_SPRG_RTAS,r3   /* 0 => not in RTAS */
@@ -949,7 +947,6 @@ start_here:
/* ptr to phys current thread */
tophys(r4,r2)
addir4,r4,THREAD/* init task's THREAD */
-   CLR_TOP32(r4)
mtspr   SPRN_SPRG_THREAD,r4
li  r3,0
mtspr   SPRN_SPRG_RTAS,r3   /* 0 => not in RTAS */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 43ddaae..3a185c5 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -151,7 +151,6 @@ turn_on_mmu:
 
 
 #define EXCEPTION_PROLOG_2 \
-   CLR_TOP32(r11); \
stw r10,_CCR(r11);  /* save registers */ \
stw r12,GPR12(r11); \
stw r9,GPR9(r11);   \
-- 
2.1.0



[PATCH] powerpc/32: Remove one insn in __bswapdi2

2016-08-05 Thread Christophe Leroy
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/kernel/misc_32.S | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index e025230..e18055c 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -578,9 +578,8 @@ _GLOBAL(__bswapdi2)
rlwimi  r9,r4,24,0,7
rlwimi  r10,r3,24,0,7
rlwimi  r9,r4,24,16,23
-   rlwimi  r10,r3,24,16,23
+   rlwimi  r4,r3,24,16,23
mr  r3,r9
-   mr  r4,r10
blr
 
 #ifdef CONFIG_SMP
-- 
2.1.0



Re: [PATCH v13 3/6] CPM/QE: use genalloc to manage CPM/QE muram

2016-08-05 Thread Christophe Leroy



Le 30/11/2015 à 03:48, Zhao Qiang a écrit :

Use genalloc to manage CPM/QE muram instead of rheap.

Signed-off-by: Zhao Qiang 
---
Changes for v9:
- splitted from patch 3/5, modify cpm muram management functions.
Changes for v10:
- modify cpm muram first, then move to qe_common
- modify commit.
Changes for v11:
- factor out the common alloc code
- modify min_alloc_order to zero for cpm_muram_alloc_fixed.
Changes for v12:
- Nil
Changes for v13:
- rebase

 arch/powerpc/include/asm/cpm.h   |   3 +
 arch/powerpc/platforms/Kconfig   |   4 +-
 arch/powerpc/sysdev/cpm_common.c | 126 +++
 lib/genalloc.c   |   2 +-
 4 files changed, 94 insertions(+), 41 deletions(-)



With that patch applied, I get the following Oops on a 8xx (Which has a 
CPM1).


cpm_muram_init() is called from setup_arch()

It seems that gen_pool_add() tries to kmalloc() memory but the SLAB is 
not available yet.


[0.00] Unable to handle kernel paging request for data at 
address 0x0008

[0.00] Faulting instruction address: 0xc01acce0
[0.00] Oops: Kernel access of bad area, sig: 11 [#1]
[0.00] PREEMPT CMPC885
[0.00] CPU: 0 PID: 0 Comm: swapper Not tainted 
4.4.14-s3k-dev-g0886ed8-svn #5

[0.00] task: c05183e0 ti: c0536000 task.ti: c0536000
[0.00] NIP: c01acce0 LR: c0011068 CTR: 
[0.00] REGS: c0537e50 TRAP: 0300   Not tainted 
(4.4.14-s3k-dev-g0886ed8-svn)

[0.00] MSR: 1032   CR: 28044428  XER: 
[0.00] DAR: 0008 DSISR: c000
GPR00: c0011068 c0537f00 c05183e0  9000  0bc0 

GPR08: ff003000 ff00b000 ff003bbf  22044422 100d43a8  
07ff94e8
GPR16:  07bb5d70  07ff81f4 07ff81f4 07ff81f4  

GPR24: 07ffb3a0 07fe7628 c055 c7ffa190 c054 ff003bbf  
0001

[0.00] NIP [c01acce0] gen_pool_add_virt+0x14/0xdc
[0.00] LR [c0011068] cpm_muram_init+0xd4/0x18c
[0.00] Call Trace:
[0.00] [c0537f00] [0200] 0x200 (unreliable)
[0.00] [c0537f20] [c0011068] cpm_muram_init+0xd4/0x18c
[0.00] [c0537f70] [c0494684] cpm_reset+0xb4/0xc8
[0.00] [c0537f90] [c0494c64] cmpc885_setup_arch+0x10/0x30
[0.00] [c0537fa0] [c0493cd4] setup_arch+0x130/0x168
[0.00] [c0537fb0] [c04906bc] start_kernel+0x88/0x380
[0.00] [c0537ff0] [c0002224] start_here+0x38/0x98
[0.00] Instruction dump:
[0.00] 91430010 91430014 80010014 83e1000c 7c0803a6 38210010 
4e800020 7c0802a6
[0.00] 9421ffe0 bf61000c 90010024 7c7e1b78 <80630008> 7c9c2378 
7cc31c30 3863001f

[0.00] ---[ end trace dc8fa200cb88537f ]---


[PATCH] gpio: max730x: set gpiochip data pointeur before using it

2016-08-08 Thread Christophe Leroy
gpiochip_add_data() has to be called before calling
max7301_direction_input()

[4.389883] Unable to handle kernel paging request for data at address 
0x0018
[4.397282] Faulting instruction address: 0xc01a8cbc
[4.402023] Oops: Kernel access of bad area, sig: 11 [#1]
[4.407331] PREEMPT CMPC885
[4.410131] CPU: 0 PID: 6 Comm: kworker/u2:0 Not tainted 4.5.0-gacdfdee #39
[4.418592] Workqueue: deferwq deferred_probe_work_func
[4.423711] task: c60798b0 ti: c608a000 task.ti: c608a000
[4.429038] NIP: c01a8cbc LR: c01a8e24 CTR: c01ff028
[4.433953] REGS: c608bad0 TRAP: 0300   Not tainted  
(4.5.0-s3k-dev-gacdfdee-svn-dirty)
[4.441847] MSR: 9032   CR: 33039553  XER: a000f940
[4.448395] DAR: 0018 DSISR: c000
GPR00: c01a8e24 c608bb80 c60798b0 c60d6f6c 0004 0002 07de2900 0070
GPR08:   c608a000 1032 35039553  c002f37c c6010b64
GPR16: c6010a48 c6010a14 c6010a00  c045 c0453568 c0453438 c050db14
GPR24: c62662bc 0009 ffaa c60d6f5d 0001   
[4.480371] NIP [c01a8cbc] max7301_direction_input+0x20/0x9c
[4.485951] LR [c01a8e24] __max730x_probe+0xec/0x138
[4.490812] Call Trace:
[4.493268] [c608bba0] [c01a8e24] __max730x_probe+0xec/0x138
[4.498878] [c608bbc0] [c01cc368] driver_probe_device+0x190/0x38c
[4.504895] [c608bbf0] [c01ca918] bus_for_each_drv+0x58/0xb4
[4.510489] [c608bc20] [c01cc04c] __device_attach+0x8c/0x110
[4.516082] [c608bc50] [c01cab80] bus_probe_device+0x34/0xb8
[4.521673] [c608bc70] [c01c96c8] device_add+0x3c0/0x598
[4.526925] [c608bcb0] [c0200f90] spi_add_device+0x114/0x160
[4.532512] [c608bcd0] [c02018d0] spi_register_master+0x6e0/0x7c8
[4.538537] [c608bd20] [c02019fc] devm_spi_register_master+0x44/0x8c
[4.544824] [c608bd40] [c0203854] of_fsl_spi_probe+0x458/0x57c
[4.550587] [c608bda0] [c01cd828] platform_drv_probe+0x30/0x74
[4.556366] [c608bdb0] [c01cc368] driver_probe_device+0x190/0x38c
[4.562383] [c608bde0] [c01ca918] bus_for_each_drv+0x58/0xb4
[4.567977] [c608be10] [c01cc04c] __device_attach+0x8c/0x110
[4.573572] [c608be40] [c01cab80] bus_probe_device+0x34/0xb8
[4.579170] [c608be60] [c01cb9b4] deferred_probe_work_func+0xa4/0xc4
[4.585438] [c608be80] [c0029c04] process_one_work+0x22c/0x414
[4.591201] [c608bea0] [c002a100] worker_thread+0x314/0x5c0
[4.596722] [c608bef0] [c002f444] kthread+0xc8/0xcc
[4.601538] [c608bf40] [c000af84] ret_from_kernel_thread+0x5c/0x64
[4.607596] Instruction dump:
[4.610530] 7c0803a6 bba10014 38210020 4e800020 7c0802a6 9421ffe0 38840004 
bf810010
[4.618188] 90010024 549cf0be 83c30010 549d0f7c <813e0018> 7fc3f378 7d3f2430 
57ff07fe
[4.626041] ---[ end trace 303adb021dd4caf2 ]---

fixes: 5e45e01916197 ("gpio: max730x: use gpiochip data pointer")
Cc: sta...@vger.kernel.org
Signed-off-by: Christophe Leroy 
---
 drivers/gpio/gpio-max730x.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c
index 0880736..946d091 100644
--- a/drivers/gpio/gpio-max730x.c
+++ b/drivers/gpio/gpio-max730x.c
@@ -192,6 +192,10 @@ int __max730x_probe(struct max7301 *ts)
ts->chip.parent = dev;
ts->chip.owner = THIS_MODULE;
 
+   ret = gpiochip_add_data(&ts->chip, ts);
+   if (ret)
+   goto exit_destroy;
+
/*
 * initialize pullups according to platform data and cache the
 * register values for later use.
@@ -213,10 +217,6 @@ int __max730x_probe(struct max7301 *ts)
}
}
 
-   ret = gpiochip_add_data(&ts->chip, ts);
-   if (ret)
-   goto exit_destroy;
-
return ret;
 
 exit_destroy:
-- 
2.1.0



Re: [PATCH v13 3/6] CPM/QE: use genalloc to manage CPM/QE muram

2016-08-08 Thread christophe leroy


Le 08/08/2016 à 05:00, Qiang Zhao a écrit :

On 6/8/2016 03:48AM,  Christophe Leroy  wrote :


-Original Message-
From: Christophe Leroy [mailto:christophe.le...@c-s.fr]
Sent: Saturday, August 06, 2016 12:59 AM
To: Zhao Qiang ; lau...@codeaurora.org
Cc: catalin.mari...@arm.com; linux-kernel@vger.kernel.org; Scott Wood
; o...@lixom.net; a...@linux-foundation.org; linuxppc-
d...@lists.ozlabs.org; x@freescale.com
Subject: Re: [PATCH v13 3/6] CPM/QE: use genalloc to manage CPM/QE muram



Le 30/11/2015 à 03:48, Zhao Qiang a écrit :

Use genalloc to manage CPM/QE muram instead of rheap.

Signed-off-by: Zhao Qiang 
---
Changes for v9:
- splitted from patch 3/5, modify cpm muram management functions.
Changes for v10:
- modify cpm muram first, then move to qe_common
- modify commit.
Changes for v11:
- factor out the common alloc code
- modify min_alloc_order to zero for cpm_muram_alloc_fixed.
Changes for v12:
- Nil
Changes for v13:
- rebase

 arch/powerpc/include/asm/cpm.h   |   3 +
 arch/powerpc/platforms/Kconfig   |   4 +-
 arch/powerpc/sysdev/cpm_common.c | 126

+++

 lib/genalloc.c   |   2 +-
 4 files changed, 94 insertions(+), 41 deletions(-)



With that patch applied, I get the following Oops on a 8xx (Which has a CPM1).

cpm_muram_init() is called from setup_arch()

It seems that gen_pool_add() tries to kmalloc() memory but the SLAB is not
available yet.



Thank you for your comments, I can't find a 8xx board, would you like to test 
the patch
Attached on your board?


Thanks for your support (indeed I only received your mail a few minutes, 
that is after I proposed another patch).


Your patch will not work, because initcalls are called too late. The 8xx 
needs the SMCs from the CPM for console, that is long before initcalls 
are called.


I sent a proposed patch approximatly 2 hours ago, it is called "[PATCH] 
soc: fsl/qe: fix Oops on CPM1 (and likely CPM2)"

That one works. Could you have a look ?

Christophe

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus



[PATCH 1/3] net: fs_enet: merge NAPI RX and NAPI TX

2016-08-24 Thread Christophe Leroy
Initially, a NAPI TX routine has been implemented separately from
NAPI RX, as done on the freescale/gianfar driver.

By merging NAPI RX and NAPI TX, we reduce the amount of TX completion
interrupts.

Handling of the budget in association with TX interrupts is based on
indications provided at https://wiki.linuxfoundation.org/networking/napi

At the same time, we fix an issue in the handling of fep->tx_free:

It is only when fep->tx_free goes up to MAX_SKB_FRAGS that
we need to wake up the queue. There is no need to call
netif_wake_queue() at every packet successfully transmitted.

Signed-off-by: Christophe Leroy 
---
 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  | 259 +
 drivers/net/ethernet/freescale/fs_enet/fs_enet.h   |  16 +-
 drivers/net/ethernet/freescale/fs_enet/mac-fcc.c   |  57 ++---
 drivers/net/ethernet/freescale/fs_enet/mac-fec.c   |  57 ++---
 drivers/net/ethernet/freescale/fs_enet/mac-scc.c   |  57 ++---
 5 files changed, 153 insertions(+), 293 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 61fd486..7cd3ef9 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -79,8 +79,8 @@ static void skb_align(struct sk_buff *skb, int align)
skb_reserve(skb, align - off);
 }
 
-/* NAPI receive function */
-static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
+/* NAPI function */
+static int fs_enet_napi(struct napi_struct *napi, int budget)
 {
struct fs_enet_private *fep = container_of(napi, struct 
fs_enet_private, napi);
struct net_device *dev = fep->ndev;
@@ -90,9 +90,100 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int 
budget)
int received = 0;
u16 pkt_len, sc;
int curidx;
+   int dirtyidx, do_wake, do_restart;
 
-   if (budget <= 0)
-   return received;
+   spin_lock(&fep->tx_lock);
+   bdp = fep->dirty_tx;
+
+   /* clear status bits for napi*/
+   (*fep->ops->napi_clear_event)(dev);
+
+   do_wake = do_restart = 0;
+   while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
+   dirtyidx = bdp - fep->tx_bd_base;
+
+   if (fep->tx_free == fep->tx_ring)
+   break;
+
+   skb = fep->tx_skbuff[dirtyidx];
+
+   /*
+* Check for errors.
+*/
+   if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+ BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
+
+   if (sc & BD_ENET_TX_HB) /* No heartbeat */
+   fep->stats.tx_heartbeat_errors++;
+   if (sc & BD_ENET_TX_LC) /* Late collision */
+   fep->stats.tx_window_errors++;
+   if (sc & BD_ENET_TX_RL) /* Retrans limit */
+   fep->stats.tx_aborted_errors++;
+   if (sc & BD_ENET_TX_UN) /* Underrun */
+   fep->stats.tx_fifo_errors++;
+   if (sc & BD_ENET_TX_CSL)/* Carrier lost */
+   fep->stats.tx_carrier_errors++;
+
+   if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | 
BD_ENET_TX_UN)) {
+   fep->stats.tx_errors++;
+   do_restart = 1;
+   }
+   } else
+   fep->stats.tx_packets++;
+
+   if (sc & BD_ENET_TX_READY) {
+   dev_warn(fep->dev,
+"HEY! Enet xmit interrupt and TX_READY.\n");
+   }
+
+   /*
+* Deferred means some collisions occurred during transmit,
+* but we eventually sent the packet OK.
+*/
+   if (sc & BD_ENET_TX_DEF)
+   fep->stats.collisions++;
+
+   /* unmap */
+   if (fep->mapped_as_page[dirtyidx])
+   dma_unmap_page(fep->dev, CBDR_BUFADDR(bdp),
+  CBDR_DATLEN(bdp), DMA_TO_DEVICE);
+   else
+   dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+CBDR_DATLEN(bdp), DMA_TO_DEVICE);
+
+   /*
+* Free the sk buffer associated with this last transmit.
+*/
+   if (skb) {
+   dev_kfree_skb(skb);
+   fep->tx_skbuff[dirtyidx] = NULL;
+   }
+
+   /*
+* Update pointer to next buffer descriptor to be transmitted.
+*/
+   if ((sc & BD_ENET_TX_WRAP) == 0)
+ 

[PATCH 2/3] net: fs_enet: don't unmap DMA when packet len is below copybreak

2016-08-24 Thread Christophe Leroy
When the length of the packet is below the defined copybreak limit,
the received packet is copied into a newly allocated skb in order
to reuse the skb. This is only interesting if it allow us to avoid
a new DMA mapping. We shall therefore not DMA unmap and remap the
skb->data. Instead, we invalidate the cache
with dma_sync_single_for_cpu() once the received data has been
copied into the new skb.

The following measures have been obtained on a mpc885 running at 132Mhz.
Measurement is done using the timebase with packets sent to the target
with 'ping -s 1' (packet len is 60):
* Without this patch: 182 TB ticks
* With this patch: 143 TB ticks

As a comparison, if we set the copybreak limit to 0, then we get
148 TB ticks. It means that without this patch, duration is even
worse when copying received data to a new skb instead of
allocating a new skb for next packet to be received

Signed-off-by: Christophe Leroy 
---
 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  | 36 --
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 7cd3ef9..addcae6 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -221,21 +221,10 @@ static int fs_enet_napi(struct napi_struct *napi, int 
budget)
if (sc & BD_ENET_RX_OV)
fep->stats.rx_crc_errors++;
 
-   skb = fep->rx_skbuff[curidx];
-
-   dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
-   L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
-   DMA_FROM_DEVICE);
-
-   skbn = skb;
-
+   skbn = fep->rx_skbuff[curidx];
} else {
skb = fep->rx_skbuff[curidx];
 
-   dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
-   L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
-   DMA_FROM_DEVICE);
-
/*
 * Process the incoming frame.
 */
@@ -251,12 +240,30 @@ static int fs_enet_napi(struct napi_struct *napi, int 
budget)
skb_copy_from_linear_data(skb,
  skbn->data, pkt_len);
swap(skb, skbn);
+   dma_sync_single_for_cpu(fep->dev,
+   CBDR_BUFADDR(bdp),
+   L1_CACHE_ALIGN(pkt_len),
+   DMA_FROM_DEVICE);
}
} else {
skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
 
-   if (skbn)
+   if (skbn) {
+   dma_addr_t dma;
+
skb_align(skbn, ENET_RX_ALIGN);
+
+   dma_unmap_single(fep->dev,
+   CBDR_BUFADDR(bdp),
+   L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+   DMA_FROM_DEVICE);
+
+   dma = dma_map_single(fep->dev,
+   skbn->data,
+   L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+   DMA_FROM_DEVICE);
+   CBDW_BUFADDR(bdp, dma);
+   }
}
 
if (skbn != NULL) {
@@ -271,9 +278,6 @@ static int fs_enet_napi(struct napi_struct *napi, int 
budget)
}
 
fep->rx_skbuff[curidx] = skbn;
-   CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
-L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
-DMA_FROM_DEVICE));
CBDW_DATLEN(bdp, 0);
CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
 
-- 
2.1.0



[PATCH 0/3] Optimisation of fs_enet ethernet driver

2016-08-24 Thread Christophe Leroy
This set optimises the freescale fs_enet ethernet driver:
1/ Merge of RX and TX NAPI functions in order to limit the amount of
interrupts
2/ Do not unmap DMA when packets len is below copybreak, otherwise there
is no benefit in copying the skb instead of allocating a new one
3/ Make copybreak value configurable as the optimised value is not the
same on all targets

chleroy (3):
  net: fs_enet: merge NAPI RX and NAPI TX
  net: fs_enet: don't unmap DMA when packet len is below copybreak
  net: fs_enet: make rx_copybreak value configurable

 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  | 303 +
 drivers/net/ethernet/freescale/fs_enet/fs_enet.h   |  16 +-
 drivers/net/ethernet/freescale/fs_enet/mac-fcc.c   |  57 +---
 drivers/net/ethernet/freescale/fs_enet/mac-fec.c   |  57 +---
 drivers/net/ethernet/freescale/fs_enet/mac-scc.c   |  57 +---
 include/linux/fs_enet_pd.h |   1 -
 6 files changed, 178 insertions(+), 313 deletions(-)

-- 
2.1.0



[PATCH 3/3] net: fs_enet: make rx_copybreak value configurable

2016-08-24 Thread Christophe Leroy
Measurement shows that on a MPC8xx running at 132MHz, the optimal
limit is 112:
* 114 bytes packets are processed in 147 TB ticks with higher copybreak
* 114 bytes packets are processed in 148 TB ticks with lower copybreak
* 128 bytes packets are processed in 154 TB ticks with higher copybreak
* 128 bytes packets are processed in 148 TB ticks with lower copybreak
* 238 bytes packets are processed in 172 TB ticks with higher copybreak
* 238 bytes packets are processed in 148 TB ticks with lower copybreak

However it might be different on other processors
and/or frequencies. So it is useful to make it configurable.

Signed-off-by: Christophe Leroy 
---
 drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c | 8 +---
 include/linux/fs_enet_pd.h| 1 -
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index addcae6..b59bbf8 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -60,6 +60,10 @@ module_param(fs_enet_debug, int, 0);
 MODULE_PARM_DESC(fs_enet_debug,
 "Freescale bitmapped debugging message enable value");
 
+static int rx_copybreak = 240;
+module_param(rx_copybreak, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(rx_copybreak, "Receive copy threshold");
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void fs_enet_netpoll(struct net_device *dev);
 #endif
@@ -84,7 +88,6 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
 {
struct fs_enet_private *fep = container_of(napi, struct 
fs_enet_private, napi);
struct net_device *dev = fep->ndev;
-   const struct fs_platform_info *fpi = fep->fpi;
cbd_t __iomem *bdp;
struct sk_buff *skb, *skbn;
int received = 0;
@@ -232,7 +235,7 @@ static int fs_enet_napi(struct napi_struct *napi, int 
budget)
pkt_len = CBDR_DATLEN(bdp) - 4; /* remove CRC */
fep->stats.rx_bytes += pkt_len + 4;
 
-   if (pkt_len <= fpi->rx_copybreak) {
+   if (pkt_len <= rx_copybreak) {
/* +2 to make IP header L1 cache aligned */
skbn = netdev_alloc_skb(dev, pkt_len + 2);
if (skbn != NULL) {
@@ -905,7 +908,6 @@ static int fs_enet_probe(struct platform_device *ofdev)
 
fpi->rx_ring = 32;
fpi->tx_ring = 64;
-   fpi->rx_copybreak = 240;
fpi->napi_weight = 17;
fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
if (!fpi->phy_node && of_phy_is_fixed_link(ofdev->dev.of_node)) {
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 77d783f..376600e 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -138,7 +138,6 @@ struct fs_platform_info {
 
int rx_ring, tx_ring;   /* number of buffers on rx */
__u8 macaddr[ETH_ALEN]; /* mac address */
-   int rx_copybreak;   /* limit we copy small frames  */
int napi_weight;/* NAPI weight */
 
int use_rmii;   /* use RMII mode   */
-- 
2.1.0



Re: [PATCH] net: phy: micrel: remove suspend/resume

2016-08-24 Thread Christophe Leroy



Le 23/08/2016 à 21:03, Florian Fainelli a écrit :

+others,

On 08/23/2016 04:13 AM, Christophe Leroy wrote:

In ERRATA DS8700A dated 05 May 2016, Microship recommends to
not use software power down mode on KSZ8041 family.


s/Microship/Microchip/


They say they have no plan to fix this ERRATA in future releases.


The errata applies to specific revisions, is this revision present in
the lower 4 bits of the MII_PHYSID2 register such that it could be used
to key the disabling of the power down?


It doesn't seem clear to me how this could/should be handled.

According to the documentation, all variants have the same ID 0x0022151x 
with revision x. A3 has ID 0x00221512 and A4 has 0x00221513.
According to the doc, the KSZ8041RNLI should has same ID. But according 
to micrel driver, it has ID 0x00221537. And the buggy revision of that 
one is rev A. Is it what the 7 means ?


The ERRATA applies to KSZ8041NL revision A4 and to KSZ8041NL-AM revision 
A3. My understanding it that both variants have ID 0x0022151x, ie 
KSZ8041NL-AM revision A3 has ID 0x00221512 and KSZ8041NL revision A4 has 
ID 0x00221513. But KSZ8041NL revision A3 also has ID 0x00221512 and the 
ERRATA doesn't apply to it.


So what can be done really ? Only apply the fix to ID 0x00221513 (which 
is what I need as I have KSZ8041NL revision A4 on my boards) ? Or apply 
it for all KSZ8041 and KSZ8041RNLI to be on the safe side ?


Christophe






http://ww1.microchip.com/downloads/en/DeviceDoc/8700A.pdf

Signed-off-by: Christophe Leroy 
---
 drivers/net/phy/micrel.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 053e879..f456c55 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -837,8 +837,6 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
-   .suspend= genphy_suspend,
-   .resume = genphy_resume,
 }, {
.phy_id = PHY_ID_KSZ8041RNLI,
.phy_id_mask= MICREL_PHY_ID_MASK,
@@ -856,8 +854,6 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
-   .suspend= genphy_suspend,
-   .resume = genphy_resume,
 }, {
.phy_id = PHY_ID_KSZ8051,
.phy_id_mask= MICREL_PHY_ID_MASK,






Re: [PATCH 1/3] net: fs_enet: merge NAPI RX and NAPI TX

2016-08-24 Thread Christophe Leroy



Le 24/08/2016 à 15:07, Eric Dumazet a écrit :

On Wed, 2016-08-24 at 12:36 +0200, Christophe Leroy wrote:

Initially, a NAPI TX routine has been implemented separately from
NAPI RX, as done on the freescale/gianfar driver.

By merging NAPI RX and NAPI TX, we reduce the amount of TX completion
interrupts.

Handling of the budget in association with TX interrupts is based on
indications provided at https://wiki.linuxfoundation.org/networking/napi

At the same time, we fix an issue in the handling of fep->tx_free:

It is only when fep->tx_free goes up to MAX_SKB_FRAGS that
we need to wake up the queue. There is no need to call
netif_wake_queue() at every packet successfully transmitted.

Signed-off-by: Christophe Leroy 
---
 .../net/ethernet/freescale/fs_enet/fs_enet-main.c  | 259 +
 drivers/net/ethernet/freescale/fs_enet/fs_enet.h   |  16 +-
 drivers/net/ethernet/freescale/fs_enet/mac-fcc.c   |  57 ++---
 drivers/net/ethernet/freescale/fs_enet/mac-fec.c   |  57 ++---
 drivers/net/ethernet/freescale/fs_enet/mac-scc.c   |  57 ++---
 5 files changed, 153 insertions(+), 293 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 61fd486..7cd3ef9 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -79,8 +79,8 @@ static void skb_align(struct sk_buff *skb, int align)
skb_reserve(skb, align - off);
 }

-/* NAPI receive function */
-static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
+/* NAPI function */
+static int fs_enet_napi(struct napi_struct *napi, int budget)
 {
struct fs_enet_private *fep = container_of(napi, struct 
fs_enet_private, napi);
struct net_device *dev = fep->ndev;
@@ -90,9 +90,100 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int 
budget)
int received = 0;
u16 pkt_len, sc;
int curidx;
+   int dirtyidx, do_wake, do_restart;

-   if (budget <= 0)
-   return received;
+   spin_lock(&fep->tx_lock);
+   bdp = fep->dirty_tx;
+
+   /* clear status bits for napi*/
+   (*fep->ops->napi_clear_event)(dev);
+
+   do_wake = do_restart = 0;
+   while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {


I am afraid you could live lock here on SMP.

You should make sure you do not loop forever, not assuming cpu is faster
than NIC.


This peace of code is pure move of existing code below

-static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
-{
-   struct fs_enet_private *fep = container_of(napi, struct fs_enet_private,
-  napi_tx);
-   struct net_device *dev = fep->ndev;
-   cbd_t __iomem *bdp;
-   struct sk_buff *skb;
-   int dirtyidx, do_wake, do_restart;
-   u16 sc;
-   int has_tx_work = 0;
-
-   spin_lock(&fep->tx_lock);
-   bdp = fep->dirty_tx;
-
-   /* clear TX status bits for napi*/
-   (*fep->ops->napi_clear_tx_event)(dev);
-
-   do_wake = do_restart = 0;
-   while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
-   dirtyidx = bdp - fep->tx_bd_base;

What should be done instead (any exemple driver doing it the good way ?) 
and should that change be part of that patch or a another new one ?


Christophe






+   dirtyidx = bdp - fep->tx_bd_base;
+
+   if (fep->tx_free == fep->tx_ring)
+   break;
+
+   skb = fep->tx_skbuff[dirtyidx];
+
+   /*
+* Check for errors.
+*/
+   if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+ BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
+
+   if (sc & BD_ENET_TX_HB) /* No heartbeat */
+   fep->stats.tx_heartbeat_errors++;
+   if (sc & BD_ENET_TX_LC) /* Late collision */
+   fep->stats.tx_window_errors++;
+   if (sc & BD_ENET_TX_RL) /* Retrans limit */
+   fep->stats.tx_aborted_errors++;
+   if (sc & BD_ENET_TX_UN) /* Underrun */
+   fep->stats.tx_fifo_errors++;
+   if (sc & BD_ENET_TX_CSL)/* Carrier lost */
+   fep->stats.tx_carrier_errors++;
+
+   if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | 
BD_ENET_TX_UN)) {
+   fep->stats.tx_errors++;
+   do_restart = 1;
+   }
+   } else
+   fep->stats.tx_packets++;
+
+   if (sc & BD_ENET_TX_READY) {
+   dev_warn(fep->dev,
+ 

Re: [PATCH] net: phy: micrel: remove suspend/resume

2016-08-25 Thread Christophe Leroy



Le 26/08/2016 à 06:35, Florian Fainelli a écrit :

Le 24/08/2016 à 07:14, Christophe Leroy a écrit :



Le 23/08/2016 à 21:03, Florian Fainelli a écrit :

+others,

On 08/23/2016 04:13 AM, Christophe Leroy wrote:

In ERRATA DS8700A dated 05 May 2016, Microship recommends to
not use software power down mode on KSZ8041 family.


s/Microship/Microchip/


They say they have no plan to fix this ERRATA in future releases.


The errata applies to specific revisions, is this revision present in
the lower 4 bits of the MII_PHYSID2 register such that it could be used
to key the disabling of the power down?


It doesn't seem clear to me how this could/should be handled.

According to the documentation, all variants have the same ID 0x0022151x
with revision x. A3 has ID 0x00221512 and A4 has 0x00221513.
According to the doc, the KSZ8041RNLI should has same ID. But according
to micrel driver, it has ID 0x00221537. And the buggy revision of that
one is rev A. Is it what the 7 means ?


Humm the revision is typically stored on 4 bits, so 0x7 could mean
anything here, it really depends if how they are allocating their revision.

0b -> A0
0b0001 -> A1
...
0b0110 -> A6
0b0111 -> A7?

Who knows.



The ERRATA applies to KSZ8041NL revision A4 and to KSZ8041NL-AM revision
A3. My understanding it that both variants have ID 0x0022151x, ie
KSZ8041NL-AM revision A3 has ID 0x00221512 and KSZ8041NL revision A4 has
ID 0x00221513. But KSZ8041NL revision A3 also has ID 0x00221512 and the
ERRATA doesn't apply to it.

So what can be done really ? Only apply the fix to ID 0x00221513 (which
is what I need as I have KSZ8041NL revision A4 on my boards) ? Or apply
it for all KSZ8041 and KSZ8041RNLI to be on the safe side ?


I would apply it to just the KSZ8041NL rev. A4 for now, ideally we would
want to track down the users of the KSZ8041RNLI and see if somebody
could test that, realistically, we won't be able to, so I would err on
the side of caution at the expense of slightly increased power
consumption for that particular PHY and have a broader match of all the
KSZ8041RNLI potentially affected.

Does that make sense?



What about the KSZ8041NL-AM revision A3, which has the same PHY ID as 
the KSZ8041NL revision A3 ?
Shouldn't we also have a broader match on this one in order to cover all 
cases and also be on the side of caution ?


Christophe


[PATCH] powerpc/32: fix again csum_partial_copy_generic()

2016-08-26 Thread Christophe Leroy
commit 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()") introduced a bug when destination
address is odd and len is lower than cacheline size.

In that case the resulting csum value doesn't have to be rotated one
byte because the cache-aligned copy part is skipped so no alignment
is performed.

Fixes: 7aef4136566b0 ("powerpc32: rewrite csum_partial_copy_generic()
based on copy_tofrom_user()")
Cc: sta...@vger.kernel.org

Reported-by: Alessio Igor Bogani 
Signed-off-by: Christophe Leroy 
Tested-by: Alessio Igor Bogani 
---
 arch/powerpc/lib/checksum_32.S | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S
index 0a57fe6..aa8214f 100644
--- a/arch/powerpc/lib/checksum_32.S
+++ b/arch/powerpc/lib/checksum_32.S
@@ -127,18 +127,19 @@ _GLOBAL(csum_partial_copy_generic)
stw r7,12(r1)
stw r8,8(r1)
 
-   rlwinm  r0,r4,3,0x8
-   rlwnm   r6,r6,r0,0,31   /* odd destination address: rotate one byte */
-   cmplwi  cr7,r0,0/* is destination address even ? */
addic   r12,r6,0
addir6,r4,-4
neg r0,r4
addir4,r3,-4
andi.   r0,r0,CACHELINE_MASK/* # bytes to start of cache line */
+   crset   4*cr7+eq
beq 58f
 
cmplw   0,r5,r0 /* is this more than total to do? */
blt 63f /* if not much to do */
+   rlwinm  r7,r6,3,0x8
+   rlwnm   r12,r12,r7,0,31 /* odd destination address: rotate one byte */
+   cmplwi  cr7,r7,0/* is destination address even ? */
andi.   r8,r0,3 /* get it word-aligned first */
mtctr   r8
beq+61f
-- 
2.1.0



Re: [PATCH v9 17/20] crypto: talitos: move to generic async completion

2017-10-17 Thread Christophe LEROY

Le 15/10/2017 à 11:20, Gilad Ben-Yossef a écrit :

The talitos driver starts several async crypto ops and  waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef 


Tested-by: Christophe Leroy 


---
  drivers/crypto/talitos.c | 38 +-
  1 file changed, 5 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5bd8191..9c80e0c 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2160,22 +2160,6 @@ static int ahash_import(struct ahash_request *areq, 
const void *in)
return 0;
  }
  
-struct keyhash_result {

-   struct completion completion;
-   int err;
-};
-
-static void keyhash_complete(struct crypto_async_request *req, int err)
-{
-   struct keyhash_result *res = req->data;
-
-   if (err == -EINPROGRESS)
-   return;
-
-   res->err = err;
-   complete(&res->completion);
-}
-
  static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int 
keylen,
   u8 *hash)
  {
@@ -2183,10 +2167,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 
*key, unsigned int keylen,
  
  	struct scatterlist sg[1];

struct ahash_request *req;
-   struct keyhash_result hresult;
+   struct crypto_wait wait;
int ret;
  
-	init_completion(&hresult.completion);

+   crypto_init_wait(&wait);
  
  	req = ahash_request_alloc(tfm, GFP_KERNEL);

if (!req)
@@ -2195,25 +2179,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 
*key, unsigned int keylen,
/* Keep tfm keylen == 0 during hash of the long key */
ctx->keylen = 0;
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-  keyhash_complete, &hresult);
+  crypto_req_done, &wait);
  
  	sg_init_one(&sg[0], key, keylen);
  
  	ahash_request_set_crypt(req, sg, hash, keylen);

-   ret = crypto_ahash_digest(req);
-   switch (ret) {
-   case 0:
-   break;
-   case -EINPROGRESS:
-   case -EBUSY:
-   ret = wait_for_completion_interruptible(
-   &hresult.completion);
-   if (!ret)
-   ret = hresult.err;
-   break;
-   default:
-   break;
-   }
+   ret = crypto_wait_req(crypto_ahash_digest(req), &wait);
+
ahash_request_free(req);
  
  	return ret;




Re: [PATCH v1 7/8] powerpc/Kconfig: Enable STRICT_KERNEL_RWX

2017-05-29 Thread Christophe LEROY



Le 25/05/2017 à 18:45, kbuild test robot a écrit :

Hi Balbir,

[auto build test ERROR on powerpc/next]
[also build test ERROR on v4.12-rc2 next-20170525]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Balbir-Singh/Enable-STRICT_KERNEL_RWX/20170525-150234
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allmodconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
 wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
 chmod +x ~/bin/make.cross
 # save the attached .config to linux build tree
 make.cross ARCH=powerpc

All errors (new ones prefixed by >>):


kernel//power/snapshot.c:40:28: fatal error: asm/set_memory.h: No such file or 
directory

 #include 


Looks like it is linked to commit 50327ddfb ("kernel/power/snapshot.c: 
use set_memory.h header").

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=50327ddfb

I believe that inclusion should be conditional to 
CONFIG_ARCH_HAS_SET_MEMORY, which is not set by powerpc arch, just like 
in include/linux/filter.c


Christophe



^
compilation terminated.

vim +40 kernel//power/snapshot.c

25761b6eb Rafael J. Wysocki2005-10-30  24  #include 
38b8d208a Ingo Molnar  2017-02-08  25  #include 
25761b6eb Rafael J. Wysocki2005-10-30  26  #include 
25761b6eb Rafael J. Wysocki2005-10-30  27  #include 
25761b6eb Rafael J. Wysocki2005-10-30  28  #include 
846705deb Rafael J. Wysocki2008-11-26  29  #include 
5a0e3ad6a Tejun Heo2010-03-24  30  #include 
52f5684c8 Gideon Israel Dsouza 2014-04-07  31  #include 
db5976058 Tina Ruchandani  2014-10-30  32  #include 
25761b6eb Rafael J. Wysocki2005-10-30  33
7c0f6ba68 Linus Torvalds   2016-12-24  34  #include 
25761b6eb Rafael J. Wysocki2005-10-30  35  #include 
25761b6eb Rafael J. Wysocki2005-10-30  36  #include 
25761b6eb Rafael J. Wysocki2005-10-30  37  #include 
25761b6eb Rafael J. Wysocki2005-10-30  38  #include 
50327ddfb Laura Abbott 2017-05-08  39  #ifdef CONFIG_STRICT_KERNEL_RWX
50327ddfb Laura Abbott 2017-05-08 @40  #include 
50327ddfb Laura Abbott 2017-05-08  41  #endif
25761b6eb Rafael J. Wysocki2005-10-30  42
25761b6eb Rafael J. Wysocki2005-10-30  43  #include "power.h"
25761b6eb Rafael J. Wysocki2005-10-30  44
0f5bf6d0a Laura Abbott 2017-02-06  45  #ifdef CONFIG_STRICT_KERNEL_RWX
4c0b6c10f Rafael J. Wysocki2016-07-10  46  static bool 
hibernate_restore_protection;
4c0b6c10f Rafael J. Wysocki2016-07-10  47  static bool 
hibernate_restore_protection_active;
4c0b6c10f Rafael J. Wysocki2016-07-10  48

:: The code at line 40 was first introduced by commit
:: 50327ddfbc926e68da1958e4fac51f1106f5e730 kernel/power/snapshot.c: use 
set_memory.h header

:: TO: Laura Abbott 
:: CC: Linus Torvalds 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation



[PATCH 7/7] powerpc/mm: Simplify __set_fixmap()

2017-05-29 Thread Christophe Leroy
__set_fixmap() uses __fix_to_virt() then does the boundary checks
by it self. Instead, we can use fix_to_virt() which does the
verification at build time. For this, we need to use it inline
so that GCC can see the real value of idx at buildtime.

In the meantime, we remove the 'fixmaps' variable.
This variable is set but has never been used from the beginning
(commit 2c419bdeca1d9 ("[POWERPC] Port fixmap from x86 and use
for kmap_atomic"))

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/fixmap.h | 10 +++---
 arch/powerpc/mm/pgtable_32.c  | 15 ---
 2 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/fixmap.h 
b/arch/powerpc/include/asm/fixmap.h
index 4508b322f2cd..6c40dfda5912 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -17,6 +17,7 @@
 #ifndef __ASSEMBLY__
 #include 
 #include 
+#include 
 #ifdef CONFIG_HIGHMEM
 #include 
 #include 
@@ -62,9 +63,6 @@ enum fixed_addresses {
__end_of_fixed_addresses
 };
 
-extern void __set_fixmap (enum fixed_addresses idx,
-   phys_addr_t phys, pgprot_t flags);
-
 #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START  (FIXADDR_TOP - __FIXADDR_SIZE)
 
@@ -72,5 +70,11 @@ extern void __set_fixmap (enum fixed_addresses idx,
 
 #include 
 
+static inline void __set_fixmap(enum fixed_addresses idx,
+   phys_addr_t phys, pgprot_t flags)
+{
+   map_kernel_page(fix_to_virt(idx), phys, pgprot_val(flags));
+}
+
 #endif /* !__ASSEMBLY__ */
 #endif
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index d672904bad0c..69f9b8bb61bf 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -408,18 +408,3 @@ void __kernel_map_pages(struct page *page, int numpages, 
int enable)
change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
 }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
-
-static int fixmaps;
-
-void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
-{
-   unsigned long address = __fix_to_virt(idx);
-
-   if (idx >= __end_of_fixed_addresses) {
-   BUG();
-   return;
-   }
-
-   map_kernel_page(address, phys, pgprot_val(flags));
-   fixmaps++;
-}
-- 
2.12.0



[PATCH 3/7] powerpc/mm: Fix kernel RAM protection after freeing unused memory on PPC32

2017-05-29 Thread Christophe Leroy
As seen below, allthough the init sections have been freed, the
associated memory area is still marked as executable in the
page tables.

~ dmesg
[5.860093] Freeing unused kernel memory: 592K (c057 - c0604000)

~ cat /sys/kernel/debug/kernel_page_tables
---[ Start of kernel VM ]---
0xc000-0xc0497fff4704K  rw  X  present dirty accessed shared
0xc0498000-0xc056 864K  rw present dirty accessed shared
0xc057-0xc059 192K  rw  X  present dirty accessed shared
0xc05a-0xc7ff  125312K  rw present dirty accessed shared
---[ vmalloc() Area ]---

This patch fixes that.

The implementation is done by reusing the change_page_attr()
function implemented for CONFIG_DEBUG_PAGEALLOC

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/mem.c|  1 +
 arch/powerpc/mm/mmu_decl.h   |  3 +++
 arch/powerpc/mm/pgtable_32.c | 13 ++---
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 8e9bef964dbf..250601ccc907 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -393,6 +393,7 @@ void free_initmem(void)
 {
ppc_md.progress = ppc_printk_progress;
free_initmem_default(POISON_FREE_INITMEM);
+   remap_init_ram();
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index d46128b22150..207af7ad3bda 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -94,6 +94,7 @@ extern void _tlbia(void);
 #ifdef CONFIG_PPC32
 
 extern void mapin_ram(void);
+void remap_init_ram(void);
 extern void setbat(int index, unsigned long virt, phys_addr_t phys,
   unsigned int size, pgprot_t prot);
 
@@ -105,6 +106,8 @@ struct hash_pte;
 extern struct hash_pte *Hash, *Hash_end;
 extern unsigned long Hash_size, Hash_mask;
 
+#else
+static inline void remap_init_ram(void) {}
 #endif /* CONFIG_PPC32 */
 
 extern unsigned long ioremap_bot;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index bdfee8e62a6a..0dc9c9d8fafb 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -323,8 +323,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t 
**ptep, pmd_t **pmdp)
 return(retval);
 }
 
-#ifdef CONFIG_DEBUG_PAGEALLOC
-
 static int __change_page_attr_noflush(struct page *page, pgprot_t prot)
 {
pte_t *kpte;
@@ -347,7 +345,7 @@ static int __change_page_attr_noflush(struct page *page, 
pgprot_t prot)
 /*
  * Change the page attributes of an page in the linear mapping.
  *
- * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY
+ * THIS DOES NOTHING WITH BAT MAPPINGS, DEBUG USE ONLY
  */
 static int change_page_attr(struct page *page, int numpages, pgprot_t prot)
 {
@@ -368,7 +366,16 @@ static int change_page_attr(struct page *page, int 
numpages, pgprot_t prot)
return err;
 }
 
+void remap_init_ram(void)
+{
+   struct page *page = virt_to_page(_sinittext);
+   unsigned long numpages = PFN_UP((unsigned long)_einittext) -
+PFN_DOWN((unsigned long)_sinittext);
+
+   change_page_attr(page, numpages, PAGE_KERNEL);
+}
 
+#ifdef CONFIG_DEBUG_PAGEALLOC
 void __kernel_map_pages(struct page *page, int numpages, int enable)
 {
if (PageHighMem(page))
-- 
2.12.0



[PATCH 5/7] powerpc/mm: declare some local functions static

2017-05-29 Thread Christophe Leroy
get_pteptr() and __mapin_ram_chunk() are only used locally,
so define them static

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h | 3 ---
 arch/powerpc/include/asm/nohash/32/pgtable.h | 3 ---
 arch/powerpc/mm/pgtable_32.c | 4 ++--
 3 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 7fb755880409..17c8766777f1 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -294,9 +294,6 @@ static inline void __ptep_set_access_flags(struct mm_struct 
*mm,
 #define __pte_to_swp_entry(pte)((swp_entry_t) { pte_val(pte) 
>> 3 })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 3 })
 
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
- pmd_t **pmdp);
-
 int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
 
 /* Generic accessors to PTE bits */
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 91314268f04f..589206bf0358 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -337,9 +337,6 @@ static inline void __ptep_set_access_flags(struct mm_struct 
*mm,
 #define __pte_to_swp_entry(pte)((swp_entry_t) { pte_val(pte) 
>> 3 })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 3 })
 
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
- pmd_t **pmdp);
-
 int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 46b02fe33864..d151779621fb 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -243,7 +243,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, int 
flags)
 /*
  * Map in a chunk of physical memory starting at start.
  */
-void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
+static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top)
 {
unsigned long v, s, f;
phys_addr_t p;
@@ -295,7 +295,7 @@ void __init mapin_ram(void)
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
  * the PTE pointer is unmodified if PTE is not found.
  */
-int
+static int
 get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t 
**pmdp)
 {
 pgd_t  *pgd;
-- 
2.12.0



[PATCH 2/7] powerpc/mm: Ensure change_page_attr() doesn't invalidate pinned TLBs

2017-05-29 Thread Christophe Leroy
__change_page_attr() uses flush_tlb_page().
flush_tlb_page() uses tlbie instruction, which also invalidates
pinned TLBs, which is not what we expect.

This patch modifies the implementation to use flush_tlb_kernel_range()
instead. This will make use of tlbia which will preserve pinned TLBs.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/pgtable_32.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 9c23c0965566..bdfee8e62a6a 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -325,7 +325,7 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t 
**ptep, pmd_t **pmdp)
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 
-static int __change_page_attr(struct page *page, pgprot_t prot)
+static int __change_page_attr_noflush(struct page *page, pgprot_t prot)
 {
pte_t *kpte;
pmd_t *kpmd;
@@ -339,8 +339,6 @@ static int __change_page_attr(struct page *page, pgprot_t 
prot)
if (!get_pteptr(&init_mm, address, &kpte, &kpmd))
return -EINVAL;
__set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
-   wmb();
-   flush_tlb_page(NULL, address);
pte_unmap(kpte);
 
return 0;
@@ -355,13 +353,17 @@ static int change_page_attr(struct page *page, int 
numpages, pgprot_t prot)
 {
int i, err = 0;
unsigned long flags;
+   struct page *start = page;
 
local_irq_save(flags);
for (i = 0; i < numpages; i++, page++) {
-   err = __change_page_attr(page, prot);
+   err = __change_page_attr_noflush(page, prot);
if (err)
break;
}
+   wmb();
+   flush_tlb_kernel_range((unsigned long)page_address(start),
+  (unsigned long)page_address(page));
local_irq_restore(flags);
return err;
 }
-- 
2.12.0



[PATCH 6/7] powerpc/mm: remove __this_fixmap_does_not_exist()

2017-05-29 Thread Christophe Leroy
This function has not been used since commit 9494a1e8428ea
("powerpc: use generic fixmap.h)

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/mm/pgtable_32.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index d151779621fb..d672904bad0c 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -423,8 +423,3 @@ void __set_fixmap (enum fixed_addresses idx, phys_addr_t 
phys, pgprot_t flags)
map_kernel_page(address, phys, pgprot_val(flags));
fixmaps++;
 }
-
-void __this_fixmap_does_not_exist(void)
-{
-   WARN_ON(1);
-}
-- 
2.12.0



[PATCH 4/7] powerpc/mm: Implement STRICT_KERNEL_RWX on PPC32

2017-05-29 Thread Christophe Leroy
This patch implements STRICT_KERNEL_RWX on PPC32.

As for CONFIG_DEBUG_PAGEALLOC, it deactivates BAT and LTLB mappings
in order to allow page protection setup at the level of each page.

As BAT/LTLB mappings are deactivated, there might be a performance
impact. For this reason, we make it optional and keep it OFF by default.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/Kconfig  |  3 ++-
 arch/powerpc/kernel/vmlinux.lds.S |  2 +-
 arch/powerpc/mm/init_32.c |  6 ++
 arch/powerpc/mm/pgtable_32.c  | 24 
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8b3f03b88a3a..2f40fa79c759 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -171,7 +171,8 @@ config PPC
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
-   select ARCH_HAS_STRICT_KERNEL_RWX   if PPC64 && PPC_BOOK3S
+   select ARCH_HAS_STRICT_KERNEL_RWX   if PPC32 || (PPC64 && 
PPC_BOOK3S)
+   select ARCH_OPTIONAL_KERNEL_RWX if PPC32
select HAVE_CBPF_JITif !PPC64
select HAVE_CONTEXT_TRACKINGif PPC64
select HAVE_DEBUG_KMEMLEAK
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 397382936c78..029d256bfb20 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -8,7 +8,7 @@
 #include 
 #include 
 
-#ifdef CONFIG_STRICT_KERNEL_RWX
+#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_PPC32)
 #define STRICT_ALIGN_SIZE  (1 << 24)
 #else
 #define STRICT_ALIGN_SIZE  PAGE_SIZE
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 8a7c38b8d335..7d5fee1bb116 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -113,6 +113,12 @@ void __init MMU_setup(void)
__map_without_bats = 1;
__map_without_ltlbs = 1;
}
+#ifdef CONFIG_STRICT_KERNEL_RWX
+   if (rodata_enabled) {
+   __map_without_bats = 1;
+   __map_without_ltlbs = 1;
+   }
+#endif
 }
 
 /*
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 0dc9c9d8fafb..46b02fe33864 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "mmu_decl.h"
 
@@ -375,6 +376,29 @@ void remap_init_ram(void)
change_page_attr(page, numpages, PAGE_KERNEL);
 }
 
+#ifdef CONFIG_STRICT_KERNEL_RWX
+void mark_rodata_ro(void)
+{
+   struct page *page;
+   unsigned long numpages;
+
+   page = virt_to_page(_stext);
+   numpages = PFN_UP((unsigned long)_etext) -
+  PFN_DOWN((unsigned long)_stext);
+
+   change_page_attr(page, numpages, PAGE_KERNEL_ROX);
+   /*
+* mark .rodata as read only. Use __init_begin rather than __end_rodata
+* to cover NOTES and EXCEPTION_TABLE.
+*/
+   page = virt_to_page(__start_rodata);
+   numpages = PFN_UP((unsigned long)__init_begin) -
+  PFN_DOWN((unsigned long)__start_rodata);
+
+   change_page_attr(page, numpages, PAGE_KERNEL_RO);
+}
+#endif
+
 #ifdef CONFIG_DEBUG_PAGEALLOC
 void __kernel_map_pages(struct page *page, int numpages, int enable)
 {
-- 
2.12.0



[PATCH 0/7] powerpc/mm: Fix kernel protection and implement STRICT_KERNEL_RWX on PPC32

2017-05-29 Thread Christophe Leroy
This patch set implements STRICT_KERNEL_RWX on Powerpc32
after fixing a few issues related to kernel code page protection.

It superseeds the previous patch set identified "Fix kernel protection
and implement CONFIG_DEBUG_RODATA on PPC32"

This set is based on Balbir Singh  set identified
"Enable STRICT_KERNEL_RWX" and applies on top of it.

At the end we take the opportunity to get rid of some unneccessary/outdated
fixmap stuff.

Christophe Leroy (7):
  powerpc/mm: rename map_page() to map_kernel_page() on PPC32
  powerpc/mm: Ensure change_page_attr() doesn't invalidate pinned TLBs
  powerpc/mm: Fix kernel RAM protection after freeing unused memory on
PPC32
  powerpc/mm: Implement STRICT_KERNEL_RWX on PPC32
  powerpc/mm: declare some local functions static
  powerpc/mm: remove __this_fixmap_does_not_exist()
  powerpc/mm: Simplify __set_fixmap()

 arch/powerpc/Kconfig |  3 +-
 arch/powerpc/include/asm/book3s/32/pgtable.h |  3 +-
 arch/powerpc/include/asm/fixmap.h| 10 ++--
 arch/powerpc/include/asm/nohash/32/pgtable.h |  3 +-
 arch/powerpc/kernel/vmlinux.lds.S|  2 +-
 arch/powerpc/mm/8xx_mmu.c|  2 +-
 arch/powerpc/mm/dma-noncoherent.c|  2 +-
 arch/powerpc/mm/init_32.c|  6 +++
 arch/powerpc/mm/mem.c|  5 +-
 arch/powerpc/mm/mmu_decl.h   |  4 +-
 arch/powerpc/mm/pgtable_32.c | 73 
 11 files changed, 69 insertions(+), 44 deletions(-)

-- 
2.12.0



[PATCH 1/7] powerpc/mm: rename map_page() to map_kernel_page() on PPC32

2017-05-29 Thread Christophe Leroy
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/book3s/32/pgtable.h | 2 ++
 arch/powerpc/include/asm/nohash/32/pgtable.h | 2 ++
 arch/powerpc/mm/8xx_mmu.c| 2 +-
 arch/powerpc/mm/dma-noncoherent.c| 2 +-
 arch/powerpc/mm/mem.c| 4 ++--
 arch/powerpc/mm/mmu_decl.h   | 1 -
 arch/powerpc/mm/pgtable_32.c | 8 
 7 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 26ed228d4dc6..7fb755880409 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -297,6 +297,8 @@ static inline void __ptep_set_access_flags(struct mm_struct 
*mm,
 extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
  pmd_t **pmdp);
 
+int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
+
 /* Generic accessors to PTE bits */
 static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & 
_PAGE_RW);}
 static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & 
_PAGE_DIRTY); }
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h 
b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 5134ade2e850..91314268f04f 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -340,6 +340,8 @@ static inline void __ptep_set_access_flags(struct mm_struct 
*mm,
 extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
  pmd_t **pmdp);
 
+int map_kernel_page(unsigned long va, phys_addr_t pa, int flags);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_POWERPC_NOHASH_32_PGTABLE_H */
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index 6c5025e81236..f4c6472f2fc4 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -88,7 +88,7 @@ static void mmu_mapin_immr(void)
int offset;
 
for (offset = 0; offset < IMMR_SIZE; offset += PAGE_SIZE)
-   map_page(v + offset, p + offset, f);
+   map_kernel_page(v + offset, p + offset, f);
 }
 
 /* Address of instructions to patch */
diff --git a/arch/powerpc/mm/dma-noncoherent.c 
b/arch/powerpc/mm/dma-noncoherent.c
index 2dc74e5c6458..382528475433 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -227,7 +227,7 @@ __dma_alloc_coherent(struct device *dev, size_t size, 
dma_addr_t *handle, gfp_t
 
do {
SetPageReserved(page);
-   map_page(vaddr, page_to_phys(page),
+   map_kernel_page(vaddr, page_to_phys(page),
 pgprot_val(pgprot_noncached(PAGE_KERNEL)));
page++;
vaddr += PAGE_SIZE;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index de5a90e1ceaa..8e9bef964dbf 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -305,11 +305,11 @@ void __init paging_init(void)
unsigned long end = __fix_to_virt(FIX_HOLE);
 
for (; v < end; v += PAGE_SIZE)
-   map_page(v, 0, 0); /* XXX gross */
+   map_kernel_page(v, 0, 0); /* XXX gross */
 #endif
 
 #ifdef CONFIG_HIGHMEM
-   map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+   map_kernel_page(PKMAP_BASE, 0, 0);  /* XXX gross */
pkmap_page_table = virt_to_kpte(PKMAP_BASE);
 
kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index f988db655e5b..d46128b22150 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -94,7 +94,6 @@ extern void _tlbia(void);
 #ifdef CONFIG_PPC32
 
 extern void mapin_ram(void);
-extern int map_page(unsigned long va, phys_addr_t pa, int flags);
 extern void setbat(int index, unsigned long virt, phys_addr_t phys,
   unsigned int size, pgprot_t prot);
 
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index a65c0b4c0669..9c23c0965566 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -189,7 +189,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, 
unsigned long flags,
 
err = 0;
for (i = 0; i < size && err == 0; i += PAGE_SIZE)
-   err = map_page(v+i, p+i, flags);
+   err = map_kernel_page(v+i, p+i, flags);
if (err) {
if (slab_is_available())
vunmap((void *)v);
@@ -215,7 +215,7 @@ void iounmap(volatile void __iomem *addr)
 }
 EXPORT_SYMBOL(iounmap);
 
-int map_page(unsigned long va, phys_addr_t pa, int flags)
+int map_kernel_page(unsigned long va, phys_addr_t pa, int flags)
 {
pmd_t *pd;
pte_t *pg;
@@ -255,7 +255,7 @@ void __init __mapin_ram_chunk(unsigned long o

Re: [PATCH 1/7] powerpc/mm: rename map_page() to map_kernel_page() on PPC32

2017-05-30 Thread Christophe LEROY



Le 30/05/2017 à 12:50, Michael Ellerman a écrit :

Christophe Leroy  writes:

...

Please tell me why.


Because of patch https://patchwork.ozlabs.org/patch/766777/ which 
modifies patch_instruction() to use an alternative mapping.
Compilation fails on PPC32 because map_kernel_page() only exists on 
PPC64. However we have map_page() which does the same on PPC32, hence 
the renaming.




You also moved the declaration from mmu_decl.h to book3s/32/pgtable.h,
but didn't update any includes, presumably we're confident everything
gets pgtable.h somehow?


Yes I did that so that lib/code_patching.c sees it.
All users of map_page() already include pgtable in a way or another.

Christophe


[PATCH] powerpc: ipic - fix status get and status clear

2017-10-18 Thread Christophe Leroy
IPIC Status is provided by register IPIC_SERSR and not by IPIC_SERMR
which is the mask register.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/sysdev/ipic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 16f1edd78c40..535cf1f6941c 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -846,12 +846,12 @@ void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq)
 
 u32 ipic_get_mcp_status(void)
 {
-   return ipic_read(primary_ipic->regs, IPIC_SERMR);
+   return ipic_read(primary_ipic->regs, IPIC_SERSR);
 }
 
 void ipic_clear_mcp_status(u32 mask)
 {
-   ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
+   ipic_write(primary_ipic->regs, IPIC_SERSR, mask);
 }
 
 /* Return an interrupt vector or 0 if no interrupt is pending. */
-- 
2.13.3



Re: [PATCH] powerpc: ipic - fix status get and status clear

2017-10-18 Thread Christophe LEROY



Le 19/10/2017 à 07:06, Michael Ellerman a écrit :

Christophe Leroy  writes:


IPIC Status is provided by register IPIC_SERSR and not by IPIC_SERMR
which is the mask register.


This seems like it would be a bad bug. But I guess it hasn't mattered
for some reason?


As far as I can see, this function has been added in kernel 2.6.12 but 
has never been used in-tree.


I have discovered this error while implementing NMI watchdog on a 832x 
board, ie this function is needed to know when a machine check exception 
is generated by the watchdog timer.


Christophe



cheers


diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 16f1edd78c40..535cf1f6941c 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -846,12 +846,12 @@ void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq)
  
  u32 ipic_get_mcp_status(void)

  {
-   return ipic_read(primary_ipic->regs, IPIC_SERMR);
+   return ipic_read(primary_ipic->regs, IPIC_SERSR);
  }
  
  void ipic_clear_mcp_status(u32 mask)

  {
-   ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
+   ipic_write(primary_ipic->regs, IPIC_SERSR, mask);
  }
  
  /* Return an interrupt vector or 0 if no interrupt is pending. */

--
2.13.3


Re: [PATCH v2 01/25] powerpc/8xx: Save r3 all the time in DTLB miss handler

2015-10-06 Thread Christophe Leroy



Le 29/09/2015 00:07, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:29PM +0200, Christophe Leroy wrote:

We are spending between 40 and 160 cycles with a mean of 65 cycles in
the TLB handling routines (measured with mftbl) so make it more
simple althought it adds one instruction.

Signed-off-by: Christophe Leroy 

Does this just make it simpler or does it make it faster?  What is the
performance impact?  Is the performance impact seen with or without
CONFIG_8xx_CPU6 enabled?  Without it, it looks like you're adding an
mtspr/mfspr combo in order to replace one mfspr.


The performance impact is not noticeable. Theoritically it adds 1 cycle 
on a mean of 65 cycles, that is 1.5%. Even in the worst case where we 
spend around 10% of the time in TLB handling exceptions, that represents 
only 0.15% of the total CPU time. So that's almost nothing.
Behind the fact to get in simpler, the main reason is because I need a 
third register for the following patch in the set, otherwise I would 
spend a more time saving and restoring CR several times.


Christophe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 06/25] powerpc32: iounmap() cannot vunmap() area mapped by TLBCAMs either

2015-10-06 Thread Christophe Leroy


Le 29/09/2015 01:41, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:40PM +0200, Christophe Leroy wrote:

iounmap() cannot vunmap() area mapped by TLBCAMs either

Signed-off-by: Christophe Leroy 
---
No change in v2

  arch/powerpc/mm/pgtable_32.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 7692d1b..03a073a 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -278,7 +278,9 @@ void iounmap(volatile void __iomem *addr)
 * If mapped by BATs then there is nothing to do.
 * Calling vfree() generates a benign warning.
 */
-   if (v_mapped_by_bats((unsigned long)addr)) return;
+   if (v_mapped_by_bats((unsigned long)addr) ||
+   v_mapped_by_tlbcam((unsigned long)addr))
+   return;

This is pretty pointless given that the next patch replaces both with
v_mapped_by_other().


I thought it was cleaner to first fix the bug, in order to make the 
following patch straight through, but I can skip it, no problem.


Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 07/25] powerpc32: refactor x_mapped_by_bats() and x_mapped_by_tlbcam() together

2015-10-06 Thread Christophe Leroy



Le 29/09/2015 01:47, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:42PM +0200, Christophe Leroy wrote:

x_mapped_by_bats() and x_mapped_by_tlbcam() serve the same kind of
purpose, so lets group them into a single function.

Signed-off-by: Christophe Leroy 
---
No change in v2

  arch/powerpc/mm/pgtable_32.c | 33 ++---
  1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 03a073a..3fd9083 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -67,6 +67,28 @@ extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
  #define p_mapped_by_tlbcam(x) (0UL)
  #endif /* HAVE_TLBCAM */
  
+static inline unsigned long p_mapped_by_other(phys_addr_t pa)

+{
+   unsigned long v;
+
+   v = p_mapped_by_bats(pa);
+   if (v /*&& p_mapped_by_bats(p+size-1)*/)
+   return v;
+
+   return p_mapped_by_tlbcam(pa);
+}

Did you forget to remove that comment?


No I didn't, I though it was there for a reason, it has been there since 
2005.

Do you think I should remove it ?

Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 11/25] powerpc/8xx: map 16M RAM at startup

2015-10-06 Thread Christophe Leroy



Le 29/09/2015 01:58, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:50PM +0200, Christophe Leroy wrote:

On recent kernels, with some debug options like for instance
CONFIG_LOCKDEP, the BSS requires more than 8M memory, allthough
the kernel code fits in the first 8M.
Today, it is necessary to activate CONFIG_PIN_TLB to get more than 8M
at startup, allthough pinning TLB is not necessary for that.

This patch adds a second 8M page to the initial mapping in order to
have 16M mapped regardless of CONFIG_PIN_TLB, like several other
32 bits PPC (40x, 601, ...)

Signed-off-by: Christophe Leroy 
---

Is the assumption that nobody is still running 8xx systems with only 8
MiB RAM on current kernels?


No, setup_initial_memory_limit() limits the memory to the minimum 
between 16M and the real memory size, so if a platform has only 8M, it 
will still be limited to 8M even with 16M mapped.


Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 13/25] powerpc/8xx: also use r3 in the ITLB miss in all situations

2015-10-06 Thread Christophe Leroy



Le 29/09/2015 02:00, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:54PM +0200, Christophe Leroy wrote:

We are spending between 40 and 160 cycles with a mean of 65 cycles
in the TLB handling routines (measured with mftbl) so make it more
simple althought it adds one instruction

Signed-off-by: Christophe Leroy 
---
No change in v2

  arch/powerpc/kernel/head_8xx.S | 15 ---
  1 file changed, 4 insertions(+), 11 deletions(-)

Why is this a separate patch from 1/25?

Same comments as on that patch.


Just because here there is no real need behind the simplification of the 
code, whereas the first one was a pre-requisite for the following patch.

Should I merge them together anyway ?

Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 15/25] powerpc/8xx: move 8xx SPRN defines into reg_8xx.h and add some missing ones

2015-10-06 Thread Christophe Leroy



Le 29/09/2015 02:03, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:58PM +0200, Christophe Leroy wrote:

Move 8xx SPRN defines into reg_8xx.h and add some missing ones

Signed-off-by: Christophe Leroy 
---
No change in v2

Why are they being moved?  Why are they being separated from the bit
definitions?



It was to keep asm/reg_8xx.h self sufficient for the following patch.

Also because including asm/mmu-8xx.h creates circular inclusion issue 
(mmu-8xx.h needs page.h which includes page-32.h, page-32.h includes 
cache.h, cache.h include reg.h which includes reg_8xx). The circle 
starts with an inclusion of asm/cache.h by linux/cache.h, himself 
included by linux/printk.h, and I end up with 'implicit declaration' issues.


How can I fix that ?

Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 01/25] powerpc/8xx: Save r3 all the time in DTLB miss handler

2015-10-06 Thread christophe leroy



Le 06/10/2015 18:46, Scott Wood a écrit :

On Tue, 2015-10-06 at 15:35 +0200, Christophe Leroy wrote:

Le 29/09/2015 00:07, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:50:29PM +0200, Christophe Leroy wrote:

We are spending between 40 and 160 cycles with a mean of 65 cycles in
the TLB handling routines (measured with mftbl) so make it more
simple althought it adds one instruction.

Signed-off-by: Christophe Leroy 

Does this just make it simpler or does it make it faster?  What is the
performance impact?  Is the performance impact seen with or without
CONFIG_8xx_CPU6 enabled?  Without it, it looks like you're adding an
mtspr/mfspr combo in order to replace one mfspr.



The performance impact is not noticeable. Theoritically it adds 1 cycle
on a mean of 65 cycles, that is 1.5%. Even in the worst case where we
spend around 10% of the time in TLB handling exceptions, that represents
only 0.15% of the total CPU time. So that's almost nothing.
Behind the fact to get in simpler, the main reason is because I need a
third register for the following patch in the set, otherwise I would
spend a more time saving and restoring CR several times.

FWIW, the added instruction is an SPR access and I doubt that's only one
cycle.


According to the mpc885 reference manual (table 9-1), Instruction 
Execution Timing for "Move to: mtspr, mtcrf, mtmsr, mcrxr except mtspr to LR

and CTR and to SPRs external to the core" is "serialize + 1 cycle".
Taking into account we preeceeding instructions are also 'mtspr', we are 
already serialized, so it is only one cycle I believe.

Am I interpreting it wrong ?

Christophe

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 22/25] powerpc32: move xxxxx_dcache_range() functions inline

2015-10-07 Thread Christophe Leroy



Le 29/09/2015 02:29, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:51:13PM +0200, Christophe Leroy wrote:

flush/clean/invalidate _dcache_range() functions are all very
similar and are quite short. They are mainly used in __dma_sync()
perf_event locate them in the top 3 consumming functions during
heavy ethernet activity

They are good candidate for inlining, as __dma_sync() does
almost nothing but calling them

Signed-off-by: Christophe Leroy 
---
New in v2

  arch/powerpc/include/asm/cacheflush.h | 55 +++--
  arch/powerpc/kernel/misc_32.S | 65 ---
  arch/powerpc/kernel/ppc_ksyms.c   |  2 ++
  3 files changed, 54 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index 6229e6b..6169604 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -47,12 +47,61 @@ static inline void __flush_dcache_icache_phys(unsigned long 
physaddr)
  }
  #endif
  
-extern void flush_dcache_range(unsigned long start, unsigned long stop);

  #ifdef CONFIG_PPC32
-extern void clean_dcache_range(unsigned long start, unsigned long stop);
-extern void invalidate_dcache_range(unsigned long start, unsigned long stop);
+/*
+ * Write any modified data cache blocks out to memory and invalidate them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ */
+static inline void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+   void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
+   unsigned int size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+   unsigned int i;
+
+   for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+   dcbf(addr);
+   if (i)
+   mb();   /* sync */
+}

I know this is 32-bit-specific code, but it's still bad practice to use
"unsigned int" for addresses or sizes thereof.


Ok, I can fix size, but what about start and stop ? If I change that, it 
means I also have to fix all caller. Do you expect me to do that ?


And it is very unlykely, but what if for some reason someone wants to 
invalidate the entire user address space which is 3Gbytes size ? A 
signed size would be negative here.


Christophe
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 22/25] powerpc32: move xxxxx_dcache_range() functions inline

2015-10-12 Thread christophe leroy



Le 08/10/2015 21:12, Scott Wood a écrit :

On Wed, 2015-10-07 at 14:49 +0200, Christophe Leroy wrote:

Le 29/09/2015 02:29, Scott Wood a écrit :

On Tue, Sep 22, 2015 at 06:51:13PM +0200, Christophe Leroy wrote:

flush/clean/invalidate _dcache_range() functions are all very
similar and are quite short. They are mainly used in __dma_sync()
perf_event locate them in the top 3 consumming functions during
heavy ethernet activity

They are good candidate for inlining, as __dma_sync() does
almost nothing but calling them

Signed-off-by: Christophe Leroy 
---
New in v2

   arch/powerpc/include/asm/cacheflush.h | 55
+++--
   arch/powerpc/kernel/misc_32.S | 65 ---

   arch/powerpc/kernel/ppc_ksyms.c   |  2 ++
   3 files changed, 54 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h
b/arch/powerpc/include/asm/cacheflush.h
index 6229e6b..6169604 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -47,12 +47,61 @@ static inline void
__flush_dcache_icache_phys(unsigned long physaddr)
   }
   #endif
   
-extern void flush_dcache_range(unsigned long start, unsigned long

stop);
   #ifdef CONFIG_PPC32
-extern void clean_dcache_range(unsigned long start, unsigned long
stop);
-extern void invalidate_dcache_range(unsigned long start, unsigned long
stop);
+/*
+ * Write any modified data cache blocks out to memory and invalidate
them.
+ * Does not invalidate the corresponding instruction cache blocks.
+ */
+static inline void flush_dcache_range(unsigned long start, unsigned
long stop)
+{
+ void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1));
+ unsigned int size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1);
+ unsigned int i;
+
+ for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES)
+ dcbf(addr);
+ if (i)
+ mb();   /* sync */
+}

I know this is 32-bit-specific code, but it's still bad practice to use
"unsigned int" for addresses or sizes thereof.



Ok, I can fix size, but what about start and stop ? If I change that, it
means I also have to fix all caller. Do you expect me to do that ?

start and stop are already unsigned long.


And it is very unlykely, but what if for some reason someone wants to
invalidate the entire user address space which is 3Gbytes size ? A
signed size would be negative here.

Why would size be signed?


Oops, indeed I misunderstood your comment, thought you said:
* size has to be signed int instead of unsigned int
* addresses have to be void *

I understand now that size and addresses should be unsigned long instead

Christophe


---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc32: memcpy: only use dcbz once cache is enabled

2015-09-07 Thread Christophe Leroy
memcpy() uses instruction dcbz to speed up copy by not wasting time
loading cache line with data that will be overwritten.
Some platform like mpc52xx do no have cache active at startup and
can therefore not use memcpy(). Allthough no part of the code
explicitly uses memcpy(), GCC makes calls to it.

This patch modifies memcpy() such that at startup, the 'dcbz'
instruction is replaced by 'dcbt' which is harmless if cache is not
enabled, and which helps a bit (allthough not as much as dcbz) if
cache is already enabled.

Once the initial MMU is setup, in machine_init() we patch memcpy()
by replacing the temporary 'dcbt' by 'dcbz'

Reported-by: Michal Sojka 
Signed-off-by: Christophe Leroy 
---
@Michal, can you please test it ?

 arch/powerpc/kernel/setup_32.c | 12 
 arch/powerpc/lib/copy_32.S | 11 ++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 07831ed..93715f3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define DBG(fmt...)
 
@@ -108,6 +109,15 @@ notrace unsigned long __init early_init(unsigned long 
dt_ptr)
return KERNELBASE + offset;
 }
 
+extern unsigned int ppc32_memcpy_dcbz;
+notrace void __init patch_memcpy(void)
+{
+   unsigned int instr = ppc32_memcpy_dcbz;
+
+   instr &= 0x001ff800; /* keep only RA and RB */
+   instr |= 0x7c0007ec; /* dcbz */
+   patch_instruction(&ppc32_memcpy_dcbz, instr);
+}
 
 /*
  * Find out what kind of machine we're on and save any data we need
@@ -122,6 +132,8 @@ notrace void __init machine_init(u64 dt_ptr)
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
 
+   patch_memcpy();
+
/* Do some early initialization based on the flat device tree */
early_init_devtree(__va(dt_ptr));
 
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index 2ef50c6..05b3096 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -172,7 +172,16 @@ _GLOBAL(memcpy)
mtctr   r0
beq 63f
 53:
-   dcbzr11,r6
+   /*
+* During early init, cache might not be active yet, so dcbz cannot be
+* used. We put dcbt instead of dcbz. If cache is not active, it's just
+* like a not. If cache is active, at least it prefetchs the line to be
+* overwritten.
+* Will be replaced by dcbz in machine_init()
+*/
+_GLOBAL(ppc32_memcpy_dcbz)
+   dcbtr11,r6
+
COPY_16_BYTES
 #if L1_CACHE_BYTES >= 32
COPY_16_BYTES
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Strange reports of perf events on powerpc 83xx

2015-09-02 Thread christophe leroy



Le 02/09/2015 16:20, Joakim Tjernlund a écrit :

On Thu, 2015-08-27 at 15:58 +0200, leroy christophe wrote:

Hi,

Has anybody already used 'perf' tool on powerpc MPC83xx ?

I have been succesfully using perf on MPC8xx, but on MPC83xx I get
something strange.

perf record/report reports addresses on user stack, as if it was mixing
up D accesses and I accesses.

Any idea of what the problem can be ?

We are also experiencing strange addresses on 83xx, did find the cause
of this problem?

We are using Linux 4.1.0
I identified this afternoon that the issue comes from 
perf_instruction_pointer()
which reads SPRN_SIAR instead of using the NIP register from the pt_regs 
struct

According to the MPC8323 reference manual, there is no such register.

I'm looking at the history in order to fully understand the reason.
Looks like PPC_HAVE_PMU_SUPPORT is selected for all PPC_BOOK3S_32 allthought
mpc832x has no PMU.

Christophe



# Samples: 8K of event 'cpu-clock'
# Event count (approx.): 219600
#
# Overhead  Command   Shared Object   Symbol
#     ..

#
   2.62%  perf_reseau4  libpthread-2.18.so  [.] __libc_send
   2.56%  perf_reseau4  [kernel.kallsyms]   [k] __ip_make_skb
   1.62%  perf_reseau4  [kernel.kallsyms]   [k] __ip_append_data.isra.39
   1.55%  perf_reseau4  [kernel.kallsyms]   [k] ip_finish_output
   1.33%  perf_reseau4  [unknown]   [k] 0x7d94
   1.33%  perf_reseau4  [unknown]   [k] 0x7d95
   1.28%  perf_reseau4  [unknown]   [k] 0x7d97
   1.26%  perf_reseau4  [unknown]   [k] 0x7da3
   1.24%  perf_reseau4  [unknown]   [k] 0x7d98
   1.22%  perf_reseau4  [unknown]   [k] 0x7d92
   1.22%  perf_reseau4  [unknown]   [k] 0x7d9b
   1.22%  perf_reseau4  [unknown]   [k] 0x7daa
   1.21%  perf_reseau4  [unknown]   [k] 0x7d96
   1.18%  perf_reseau4  [unknown]   [k] 0x7da7
   1.17%  perf_reseau4  [unknown]   [k] 0x7d8d
   1.17%  perf_reseau4  [unknown]   [k] 0x7d99
   1.13%  perf_reseau4  [unknown]   [k] 0x7d90
   1.13%  perf_reseau4  [unknown]   [k] 0x7da2
   1.12%  perf_reseau4  [kernel.kallsyms]   [k] __local_bh_enable_ip
   1.12%  perf_reseau4  [unknown]   [k] 0x7d9c
   1.12%  perf_reseau4  [unknown]   [k] 0x7d9e
   1.10%  perf_reseau4  [unknown]   [k] 0x7da0
   1.08%  perf_reseau4  [unknown]   [k] 0x7d9f
   1.08%  perf_reseau4  [unknown]   [k] 0x7da6
   1.05%  perf_reseau4  [unknown]   [k] 0x7da8
   1.02%  perf_reseau4  [unknown]   [k] 0x7d9a
   1.01%  perf_reseau4  [unknown]   [k] 0x7db0
   1.00%  perf_reseau4  [unknown]   [k] 0x7d89
   1.00%  perf_reseau4  [unknown]   [k] 0x7d8b
   1.00%  perf_reseau4  [unknown]   [k] 0x7dac



---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc/book3s32: Only select PPC_HAVE_PMU on e600

2015-09-03 Thread Christophe Leroy
On PPC832x, perf record/report reports martian addresses

 2.62%  perf_reseau4  libpthread-2.18.so  [.] __libc_send
 2.56%  perf_reseau4  [kernel.kallsyms]   [k] __ip_make_skb
 1.62%  perf_reseau4  [kernel.kallsyms]   [k] __ip_append_data.isra.39
 1.55%  perf_reseau4  [kernel.kallsyms]   [k] ip_finish_output
 1.33%  perf_reseau4  [unknown]   [k] 0x7d94
 1.33%  perf_reseau4  [unknown]   [k] 0x7d95
 1.28%  perf_reseau4  [unknown]   [k] 0x7d97
 1.26%  perf_reseau4  [unknown]   [k] 0x7da3
 1.24%  perf_reseau4  [unknown]   [k] 0x7d98
 1.22%  perf_reseau4  [unknown]   [k] 0x7d92
 1.22%  perf_reseau4  [unknown]   [k] 0x7d9b
 [.]

This is due to function perf_instruction_pointer() reading SPR SIAR
which doesn't exist on e300 core. The perf_instruction_pointer() is
redefined in arch/powerpc/perf/core-book3s.c when CONFIG_PPC_PERF_CTRS
is selected.

This patch moves the selection of CONFIG_PPC_HAVE_PMU in 86xx section
so that CONFIG_PPC_PERF_CTRS won't be selected for other 6xx powerpc

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/platforms/86xx/Kconfig| 1 +
 arch/powerpc/platforms/Kconfig.cputype | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/86xx/Kconfig 
b/arch/powerpc/platforms/86xx/Kconfig
index 1afd1e4..bb24d2a 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -5,6 +5,7 @@ menuconfig PPC_86xx
select FSL_SOC
select ALTIVEC
select ARCH_WANT_OPTIONAL_GPIOLIB
+   select PPC_HAVE_PMU_SUPPORT
help
  The Freescale E600 SoCs have 74xx cores.
 
diff --git a/arch/powerpc/platforms/Kconfig.cputype 
b/arch/powerpc/platforms/Kconfig.cputype
index d642cf9..aa63b12 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -143,7 +143,6 @@ config PPC_BOOK3E
 config 6xx
def_bool y
depends on PPC32 && PPC_BOOK3S
-   select PPC_HAVE_PMU_SUPPORT
 
 config TUNE_CELL
bool "Optimize for Cell Broadband Engine"
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] powerpc/book3s32: Only select PPC_HAVE_PMU on e600

2015-09-04 Thread christophe leroy



Le 04/09/2015 18:43, Scott Wood a écrit :

On Thu, Sep 03, 2015 at 11:27:03AM +0200, Christophe Leroy wrote:

On PPC832x, perf record/report reports martian addresses

  2.62%  perf_reseau4  libpthread-2.18.so  [.] __libc_send
  2.56%  perf_reseau4  [kernel.kallsyms]   [k] __ip_make_skb
  1.62%  perf_reseau4  [kernel.kallsyms]   [k] __ip_append_data.isra.39
  1.55%  perf_reseau4  [kernel.kallsyms]   [k] ip_finish_output
  1.33%  perf_reseau4  [unknown]   [k] 0x7d94
  1.33%  perf_reseau4  [unknown]   [k] 0x7d95
  1.28%  perf_reseau4  [unknown]   [k] 0x7d97
  1.26%  perf_reseau4  [unknown]   [k] 0x7da3
  1.24%  perf_reseau4  [unknown]   [k] 0x7d98
  1.22%  perf_reseau4  [unknown]   [k] 0x7d92
  1.22%  perf_reseau4  [unknown]   [k] 0x7d9b
  [.]

This is due to function perf_instruction_pointer() reading SPR SIAR
which doesn't exist on e300 core. The perf_instruction_pointer() is
redefined in arch/powerpc/perf/core-book3s.c when CONFIG_PPC_PERF_CTRS
is selected.

This patch moves the selection of CONFIG_PPC_HAVE_PMU in 86xx section
so that CONFIG_PPC_PERF_CTRS won't be selected for other 6xx powerpc

Signed-off-by: Christophe Leroy 

So, what happens when a kernel is built that supports both 83xx and 86xx?

Right, so should we define a processor feature for it ?

Plus, it's e300, not e600, that is the exception among 6xx-style cores.
Is it ? I've been looking for special register SIAR (spr 955) in several 
6xx reference manuals.

82xx doesn't have it, 52xx and 512x don't have it.
I found it only in the 86xx
Which other family has it ?

Christophe

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] powerpc/cpm1: fix compilation error with CONFIG_PPC_EARLY_DEBUG_CPM

2018-08-06 Thread Christophe Leroy
commit e8cb7a55eb8dc ("powerpc: remove superflous inclusions of
asm/fixmap.h") removed inclusion of asm/fixmap.h from files not
including objects from that file.

However, asm/mmu-8xx.h includes  call to __fix_to_virt(). The proper
way would be to include asm/fixmap.h in asm/mmu-8xx.h but it creates
an inclusion loop.

So we have to leave asm/fixmap.h in sysdep/cpm_common.c for
CONFIG_PPC_EARLY_DEBUG_CPM

  CC  arch/powerpc/sysdev/cpm_common.o
In file included from ./arch/powerpc/include/asm/mmu.h:340:0,
 from ./arch/powerpc/include/asm/reg_8xx.h:8,
 from ./arch/powerpc/include/asm/reg.h:29,
 from ./arch/powerpc/include/asm/processor.h:13,
 from ./arch/powerpc/include/asm/thread_info.h:28,
 from ./include/linux/thread_info.h:38,
 from ./arch/powerpc/include/asm/ptrace.h:159,
 from ./arch/powerpc/include/asm/hw_irq.h:12,
 from ./arch/powerpc/include/asm/irqflags.h:12,
 from ./include/linux/irqflags.h:16,
 from ./include/asm-generic/cmpxchg-local.h:6,
 from ./arch/powerpc/include/asm/cmpxchg.h:537,
 from ./arch/powerpc/include/asm/atomic.h:11,
 from ./include/linux/atomic.h:5,
 from ./include/linux/mutex.h:18,
 from ./include/linux/kernfs.h:13,
 from ./include/linux/sysfs.h:16,
 from ./include/linux/kobject.h:20,
 from ./include/linux/device.h:16,
 from ./include/linux/node.h:18,
 from ./include/linux/cpu.h:17,
 from ./include/linux/of_device.h:5,
 from arch/powerpc/sysdev/cpm_common.c:21:
arch/powerpc/sysdev/cpm_common.c: In function ‘udbg_init_cpm’:
./arch/powerpc/include/asm/mmu-8xx.h:218:25: error: implicit declaration of 
function ‘__fix_to_virt’ [-Werror=implicit-function-declaration]
 #define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
 ^
arch/powerpc/sysdev/cpm_common.c:75:7: note: in expansion of macro 
‘VIRT_IMMR_BASE’
   VIRT_IMMR_BASE);
   ^
./arch/powerpc/include/asm/mmu-8xx.h:218:39: error: ‘FIX_IMMR_BASE’ undeclared 
(first use in this function)
 #define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
   ^
arch/powerpc/sysdev/cpm_common.c:75:7: note: in expansion of macro 
‘VIRT_IMMR_BASE’
   VIRT_IMMR_BASE);
   ^
./arch/powerpc/include/asm/mmu-8xx.h:218:39: note: each undeclared identifier 
is reported only once for each function it appears in
 #define VIRT_IMMR_BASE (__fix_to_virt(FIX_IMMR_BASE))
   ^
arch/powerpc/sysdev/cpm_common.c:75:7: note: in expansion of macro 
‘VIRT_IMMR_BASE’
   VIRT_IMMR_BASE);
   ^
cc1: all warnings being treated as errors
make[1]: *** [arch/powerpc/sysdev/cpm_common.o] Error 1

Fixes: e8cb7a55eb8dc ("powerpc: remove superflous inclusions of asm/fixmap.h")
Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/fixmap.h | 1 +
 arch/powerpc/sysdev/cpm_common.c  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/powerpc/include/asm/fixmap.h 
b/arch/powerpc/include/asm/fixmap.h
index 40efdf1d2d6e..41cc15c14eee 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -16,6 +16,7 @@
 
 #ifndef __ASSEMBLY__
 #include 
+#include 
 #ifdef CONFIG_HIGHMEM
 #include 
 #include 
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 010975c3422f..b74508175b67 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
-- 
2.13.3



  1   2   3   4   5   6   7   8   9   10   >