[PATCH v2] IIO ADC support for AD7923
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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"
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
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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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()
__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
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
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
__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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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