mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
A rather big fix for a regression where we have dropped omap4 hwmod
data earlier but are not initializing it from device tree. In addition to this fix we eventually also be fix the issues in the .dts files and drivers, but that's too intrusive for the -rc cycle and must be done later on. Also a fix for a regression where we now are wrongly trying to initialize devices on secure omaps like n900 and n9* when booted using device tree. We need to set aes, sham and timer12 to disabled mode for secure devices as they are claimed by the firmware running in the secure mode. And two more legacy booting vs device tree based booting fixes for am3517 that I did not notice earlier until Nishant Menon reported these to me few days ago. With these we're good to go having v3.13 working both for legacy booting and device tree based booting, and we can then go ahed and drop the legacy booting for mach-omap2 for v3.14. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) iQIcBAABAgAGBQJSpO6+AAoJEBvUPslcq6Vz21AP/RqHy9KLpHQ2ktzEEVvg9y9y xD0fvdxfzJx7pxXCKRxkzXAybzzFlWx6YGFnILptaaiODV77gbbjdEGJa1TZrrlD lIRd9J6wdnXR9tXSxTpJjWRVYqlEdfWOtqsHIPxeSZaKOY2pxxKCx0LMdzPM/e6Q iMPL68a7TT+qbfCk5kf+1PNtn5HRIXkTrs7iHQBTftQGX9fXgkJ9Mbm3rhz4xcGA /QkWu+ax0XA9TC9abGJ5JkQ+11YA734WBnRY1Q0BDUnebTbf6FxMSvnZI+Y3d3Cz hUxBVRKVn2jnnCqZQA6cs6qX5hIcMsaGkX/ePsM4GItByxtMIwS3ANom1fIsTszP a06+xD0IctmszyYF2asRHYbT1I46QzEUwxZMKmM93Dt9CfoY9rSezDaBEXEqgOjq t/Ll8ltV1VeyGmZSiDZPj7bi73lVxKPX7buCD9pX4D5NAmZpCa1MfWKKFJNzrAsM SPbrsocl97SPyrU6V7rovmFFbQ7dGhqa40MVspiTr3QcNFToNmLCQTBbRY7uPusl Whttr1txhcsURBTHRVsp0H/eWuj0hUZ7fLwLiTHPlxrH9BLZBc/eIJgEOljmyHHU b4pju7Au3P9lqSfpkpURKMwr/KyfjzVuOAgPaM44hWJEkWcOtbVGyIrF9CH3hlYg wDEIQfHs3ZM87/dxfarb =d3MF -----END PGP SIGNATURE----- Merge tag 'omap-for-v3.13/yet-more-dt-regressions-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes A rather big fix for a regression where we have dropped omap4 hwmod data earlier but are not initializing it from device tree. In addition to this fix we eventually also be fix the issues in the .dts files and drivers, but that's too intrusive for the -rc cycle and must be done later on. Also a fix for a regression where we now are wrongly trying to initialize devices on secure omaps like n900 and n9* when booted using device tree. We need to set aes, sham and timer12 to disabled mode for secure devices as they are claimed by the firmware running in the secure mode. And two more legacy booting vs device tree based booting fixes for am3517 that I did not notice earlier until Nishant Menon reported these to me few days ago. With these we're good to go having v3.13 working both for legacy booting and device tree based booting, and we can then go ahed and drop the legacy booting for mach-omap2 for v3.14. * tag 'omap-for-v3.13/yet-more-dt-regressions-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (494 commits) ARM: dts: Fix booting for secure omaps ARM: OMAP2+: Fix the machine entry for am3517 ARM: dts: Fix missing entries for am3517 ARM: OMAP2+: Fix overwriting hwmod data with data from device tree +Linux 3.13-rc3
This commit is contained in:
commit
ed16c8c50e
@ -196,13 +196,6 @@ chmod 0644 /dev/cpu/microcode
|
||||
as root before you can use this. You'll probably also want to
|
||||
get the user-space microcode_ctl utility to use with this.
|
||||
|
||||
Powertweak
|
||||
----------
|
||||
|
||||
If you are running v0.1.17 or earlier, you should upgrade to
|
||||
version v0.99.0 or higher. Running old versions may cause problems
|
||||
with programs using shared memory.
|
||||
|
||||
udev
|
||||
----
|
||||
udev is a userspace application for populating /dev dynamically with
|
||||
@ -366,10 +359,6 @@ Intel P6 microcode
|
||||
------------------
|
||||
o <http://www.urbanmyth.org/microcode/>
|
||||
|
||||
Powertweak
|
||||
----------
|
||||
o <http://powertweak.sourceforge.net/>
|
||||
|
||||
udev
|
||||
----
|
||||
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
|
||||
|
@ -58,7 +58,7 @@
|
||||
</sect1>
|
||||
<sect1><title>Wait queues and Wake events</title>
|
||||
!Iinclude/linux/wait.h
|
||||
!Ekernel/wait.c
|
||||
!Ekernel/sched/wait.c
|
||||
</sect1>
|
||||
<sect1><title>High-resolution timers</title>
|
||||
!Iinclude/linux/ktime.h
|
||||
|
@ -7,10 +7,18 @@ The MPU contain CPUs, GIC, L2 cache and a local PRCM.
|
||||
Required properties:
|
||||
- compatible : Should be "ti,omap3-mpu" for OMAP3
|
||||
Should be "ti,omap4-mpu" for OMAP4
|
||||
Should be "ti,omap5-mpu" for OMAP5
|
||||
- ti,hwmods: "mpu"
|
||||
|
||||
Examples:
|
||||
|
||||
- For an OMAP5 SMP system:
|
||||
|
||||
mpu {
|
||||
compatible = "ti,omap5-mpu";
|
||||
ti,hwmods = "mpu"
|
||||
};
|
||||
|
||||
- For an OMAP4 SMP system:
|
||||
|
||||
mpu {
|
||||
|
@ -7,6 +7,7 @@ representation in the device tree should be done as under:-
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of
|
||||
"arm,armv8-pmuv3"
|
||||
"arm,cortex-a15-pmu"
|
||||
"arm,cortex-a9-pmu"
|
||||
"arm,cortex-a8-pmu"
|
||||
|
@ -49,7 +49,7 @@ adc@12D10000 {
|
||||
/* NTC thermistor is a hwmon device */
|
||||
ncp15wb473@0 {
|
||||
compatible = "ntc,ncp15wb473";
|
||||
pullup-uV = <1800000>;
|
||||
pullup-uv = <1800000>;
|
||||
pullup-ohm = <47000>;
|
||||
pulldown-ohm = <0>;
|
||||
io-channels = <&adc 4>;
|
||||
|
@ -6,7 +6,7 @@ SoC's in the Exynos4 family.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- comptible: should be one of the following.
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
|
||||
- "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
|
||||
|
||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5250 SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- comptible: should be one of the following.
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5420 SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- comptible: should be one of the following.
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5440 SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- comptible: should be "samsung,exynos5440-clock".
|
||||
- compatible: should be "samsung,exynos5440-clock".
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
|
@ -5,16 +5,42 @@ This is for the non-QE/CPM/GUTs GPIO controllers as found on
|
||||
|
||||
Every GPIO controller node must have #gpio-cells property defined,
|
||||
this information will be used to translate gpio-specifiers.
|
||||
See bindings/gpio/gpio.txt for details of how to specify GPIO
|
||||
information for devices.
|
||||
|
||||
The GPIO module usually is connected to the SoC's internal interrupt
|
||||
controller, see bindings/interrupt-controller/interrupts.txt (the
|
||||
interrupt client nodes section) for details how to specify this GPIO
|
||||
module's interrupt.
|
||||
|
||||
The GPIO module may serve as another interrupt controller (cascaded to
|
||||
the SoC's internal interrupt controller). See the interrupt controller
|
||||
nodes section in bindings/interrupt-controller/interrupts.txt for
|
||||
details.
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,<CHIP>-gpio" followed by "fsl,mpc8349-gpio" for
|
||||
83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
- interrupts : Interrupt mapping for GPIO IRQ.
|
||||
- interrupt-parent : Phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- gpio-controller : Marks the port as GPIO controller.
|
||||
- compatible: "fsl,<chip>-gpio" followed by "fsl,mpc8349-gpio"
|
||||
for 83xx, "fsl,mpc8572-gpio" for 85xx, or
|
||||
"fsl,mpc8610-gpio" for 86xx.
|
||||
- #gpio-cells: Should be two. The first cell is the pin number
|
||||
and the second cell is used to specify optional
|
||||
parameters (currently unused).
|
||||
- interrupt-parent: Phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- interrupts: Interrupt mapping for GPIO IRQ.
|
||||
- gpio-controller: Marks the port as GPIO controller.
|
||||
|
||||
Optional properties:
|
||||
- interrupt-controller: Empty boolean property which marks the GPIO
|
||||
module as an IRQ controller.
|
||||
- #interrupt-cells: Should be two. Defines the number of integer
|
||||
cells required to specify an interrupt within
|
||||
this interrupt controller. The first cell
|
||||
defines the pin number, the second cell
|
||||
defines additional flags (trigger type,
|
||||
trigger polarity). Note that the available
|
||||
set of trigger conditions supported by the
|
||||
GPIO module depends on the actual SoC.
|
||||
|
||||
Example of gpio-controller nodes for a MPC8347 SoC:
|
||||
|
||||
@ -22,39 +48,27 @@ Example of gpio-controller nodes for a MPC8347 SoC:
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
||||
reg = <0xc00 0x100>;
|
||||
interrupts = <74 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
interrupts = <74 0x8>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
|
||||
gpio2: gpio-controller@d00 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
||||
reg = <0xd00 0x100>;
|
||||
interrupts = <75 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
interrupts = <75 0x8>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
See booting-without-of.txt for details of how to specify GPIO
|
||||
information for devices.
|
||||
|
||||
To use GPIO pins as interrupt sources for peripherals, specify the
|
||||
GPIO controller as the interrupt parent and define GPIO number +
|
||||
trigger mode using the interrupts property, which is defined like
|
||||
this:
|
||||
|
||||
interrupts = <number trigger>, where:
|
||||
- number: GPIO pin (0..31)
|
||||
- trigger: trigger mode:
|
||||
2 = trigger on falling edge
|
||||
3 = trigger on both edges
|
||||
|
||||
Example of device using this is:
|
||||
Example of a peripheral using the GPIO module as an IRQ controller:
|
||||
|
||||
funkyfpga@0 {
|
||||
compatible = "funky-fpga";
|
||||
...
|
||||
interrupts = <4 3>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <4 3>;
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ Optional properties:
|
||||
only if property "phy-reset-gpios" is available. Missing the property
|
||||
will have the duration be 1 millisecond. Numbers greater than 1000 are
|
||||
invalid and 1 millisecond will be used instead.
|
||||
- phy-supply: regulator that powers the Ethernet PHY.
|
||||
|
||||
Example:
|
||||
|
||||
@ -25,4 +26,5 @@ ethernet@83fec000 {
|
||||
phy-mode = "mii";
|
||||
phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
|
||||
local-mac-address = [00 04 9F 01 1B B9];
|
||||
phy-supply = <®_fec_supply>;
|
||||
};
|
||||
|
17
Documentation/devicetree/bindings/rng/qcom,prng.txt
Normal file
17
Documentation/devicetree/bindings/rng/qcom,prng.txt
Normal file
@ -0,0 +1,17 @@
|
||||
Qualcomm MSM pseudo random number generator.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "qcom,prng"
|
||||
- reg : specifies base physical address and size of the registers map
|
||||
- clocks : phandle to clock-controller plus clock-specifier pair
|
||||
- clock-names : "core" clocks all registers, FIFO and circuits in PRNG IP block
|
||||
|
||||
Example:
|
||||
|
||||
rng@f9bff000 {
|
||||
compatible = "qcom,prng";
|
||||
reg = <0xf9bff000 0x200>;
|
||||
clocks = <&clock GCC_PRNG_AHB_CLK>;
|
||||
clock-names = "core";
|
||||
};
|
@ -1,5 +0,0 @@
|
||||
NVIDIA Tegra 2 SPI device
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "nvidia,tegra20-spi".
|
||||
- gpios : should specify GPIOs used for chipselect.
|
@ -32,12 +32,14 @@ est ESTeem Wireless Modems
|
||||
fsl Freescale Semiconductor
|
||||
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||
gmt Global Mixed-mode Technology, Inc.
|
||||
hisilicon Hisilicon Limited.
|
||||
hp Hewlett Packard
|
||||
ibm International Business Machines (IBM)
|
||||
idt Integrated Device Technologies, Inc.
|
||||
img Imagination Technologies Ltd.
|
||||
intercontrol Inter Control Group
|
||||
lg LG Corporation
|
||||
linux Linux-specific binding
|
||||
lsi LSI Corp. (LSI Logic)
|
||||
marvell Marvell Technology Group Ltd.
|
||||
|
14
Documentation/gpio/00-INDEX
Normal file
14
Documentation/gpio/00-INDEX
Normal file
@ -0,0 +1,14 @@
|
||||
00-INDEX
|
||||
- This file
|
||||
gpio.txt
|
||||
- Introduction to GPIOs and their kernel interfaces
|
||||
consumer.txt
|
||||
- How to obtain and use GPIOs in a driver
|
||||
driver.txt
|
||||
- How to write a GPIO driver
|
||||
board.txt
|
||||
- How to assign GPIOs to a consumer device and a function
|
||||
sysfs.txt
|
||||
- Information about the GPIO sysfs interface
|
||||
gpio-legacy.txt
|
||||
- Historical documentation of the deprecated GPIO integer interface
|
115
Documentation/gpio/board.txt
Normal file
115
Documentation/gpio/board.txt
Normal file
@ -0,0 +1,115 @@
|
||||
GPIO Mappings
|
||||
=============
|
||||
|
||||
This document explains how GPIOs can be assigned to given devices and functions.
|
||||
Note that it only applies to the new descriptor-based interface. For a
|
||||
description of the deprecated integer-based GPIO interface please refer to
|
||||
gpio-legacy.txt (actually, there is no real mapping possible with the old
|
||||
interface; you just fetch an integer from somewhere and request the
|
||||
corresponding GPIO.
|
||||
|
||||
Platforms that make use of GPIOs must select ARCH_REQUIRE_GPIOLIB (if GPIO usage
|
||||
is mandatory) or ARCH_WANT_OPTIONAL_GPIOLIB (if GPIO support can be omitted) in
|
||||
their Kconfig. Then, how GPIOs are mapped depends on what the platform uses to
|
||||
describe its hardware layout. Currently, mappings can be defined through device
|
||||
tree, ACPI, and platform data.
|
||||
|
||||
Device Tree
|
||||
-----------
|
||||
GPIOs can easily be mapped to devices and functions in the device tree. The
|
||||
exact way to do it depends on the GPIO controller providing the GPIOs, see the
|
||||
device tree bindings for your controller.
|
||||
|
||||
GPIOs mappings are defined in the consumer device's node, in a property named
|
||||
<function>-gpios, where <function> is the function the driver will request
|
||||
through gpiod_get(). For example:
|
||||
|
||||
foo_device {
|
||||
compatible = "acme,foo";
|
||||
...
|
||||
led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */
|
||||
<&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
|
||||
<&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
|
||||
|
||||
power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
This property will make GPIOs 15, 16 and 17 available to the driver under the
|
||||
"led" function, and GPIO 1 as the "power" GPIO:
|
||||
|
||||
struct gpio_desc *red, *green, *blue, *power;
|
||||
|
||||
red = gpiod_get_index(dev, "led", 0);
|
||||
green = gpiod_get_index(dev, "led", 1);
|
||||
blue = gpiod_get_index(dev, "led", 2);
|
||||
|
||||
power = gpiod_get(dev, "power");
|
||||
|
||||
The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
|
||||
gpiod_is_active_low(power) will be true).
|
||||
|
||||
ACPI
|
||||
----
|
||||
ACPI does not support function names for GPIOs. Therefore, only the "idx"
|
||||
argument of gpiod_get_index() is useful to discriminate between GPIOs assigned
|
||||
to a device. The "con_id" argument can still be set for debugging purposes (it
|
||||
will appear under error messages as well as debug and sysfs nodes).
|
||||
|
||||
Platform Data
|
||||
-------------
|
||||
Finally, GPIOs can be bound to devices and functions using platform data. Board
|
||||
files that desire to do so need to include the following header:
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
GPIOs are mapped by the means of tables of lookups, containing instances of the
|
||||
gpiod_lookup structure. Two macros are defined to help declaring such mappings:
|
||||
|
||||
GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
|
||||
GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
|
||||
|
||||
where
|
||||
|
||||
- chip_label is the label of the gpiod_chip instance providing the GPIO
|
||||
- chip_hwnum is the hardware number of the GPIO within the chip
|
||||
- dev_id is the identifier of the device that will make use of this GPIO. If
|
||||
NULL, the GPIO will be available to all devices.
|
||||
- con_id is the name of the GPIO function from the device point of view. It
|
||||
can be NULL.
|
||||
- idx is the index of the GPIO within the function.
|
||||
- flags is defined to specify the following properties:
|
||||
* GPIOF_ACTIVE_LOW - to configure the GPIO as active-low
|
||||
* GPIOF_OPEN_DRAIN - GPIO pin is open drain type.
|
||||
* GPIOF_OPEN_SOURCE - GPIO pin is open source type.
|
||||
|
||||
In the future, these flags might be extended to support more properties.
|
||||
|
||||
Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
|
||||
|
||||
A lookup table can then be defined as follows:
|
||||
|
||||
struct gpiod_lookup gpios_table[] = {
|
||||
GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW),
|
||||
};
|
||||
|
||||
And the table can be added by the board code as follows:
|
||||
|
||||
gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table));
|
||||
|
||||
The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
|
||||
|
||||
struct gpio_desc *red, *green, *blue, *power;
|
||||
|
||||
red = gpiod_get_index(dev, "led", 0);
|
||||
green = gpiod_get_index(dev, "led", 1);
|
||||
blue = gpiod_get_index(dev, "led", 2);
|
||||
|
||||
power = gpiod_get(dev, "power");
|
||||
gpiod_direction_output(power, 1);
|
||||
|
||||
Since the "power" GPIO is mapped as active-low, its actual signal will be 0
|
||||
after this code. Contrary to the legacy integer GPIO interface, the active-low
|
||||
property is handled during mapping and is thus transparent to GPIO consumers.
|
197
Documentation/gpio/consumer.txt
Normal file
197
Documentation/gpio/consumer.txt
Normal file
@ -0,0 +1,197 @@
|
||||
GPIO Descriptor Consumer Interface
|
||||
==================================
|
||||
|
||||
This document describes the consumer interface of the GPIO framework. Note that
|
||||
it describes the new descriptor-based interface. For a description of the
|
||||
deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
|
||||
|
||||
|
||||
Guidelines for GPIOs consumers
|
||||
==============================
|
||||
|
||||
Drivers that can't work without standard GPIO calls should have Kconfig entries
|
||||
that depend on GPIOLIB. The functions that allow a driver to obtain and use
|
||||
GPIOs are available by including the following file:
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
All the functions that work with the descriptor-based GPIO interface are
|
||||
prefixed with gpiod_. The gpio_ prefix is used for the legacy interface. No
|
||||
other function in the kernel should use these prefixes.
|
||||
|
||||
|
||||
Obtaining and Disposing GPIOs
|
||||
=============================
|
||||
|
||||
With the descriptor-based interface, GPIOs are identified with an opaque,
|
||||
non-forgeable handler that must be obtained through a call to one of the
|
||||
gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
|
||||
device that will use the GPIO and the function the requested GPIO is supposed to
|
||||
fulfill:
|
||||
|
||||
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
|
||||
|
||||
If a function is implemented by using several GPIOs together (e.g. a simple LED
|
||||
device that displays digits), an additional index argument can be specified:
|
||||
|
||||
struct gpio_desc *gpiod_get_index(struct device *dev,
|
||||
const char *con_id, unsigned int idx)
|
||||
|
||||
Both functions return either a valid GPIO descriptor, or an error code checkable
|
||||
with IS_ERR(). They will never return a NULL pointer.
|
||||
|
||||
Device-managed variants of these functions are also defined:
|
||||
|
||||
struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
|
||||
|
||||
struct gpio_desc *devm_gpiod_get_index(struct device *dev,
|
||||
const char *con_id,
|
||||
unsigned int idx)
|
||||
|
||||
A GPIO descriptor can be disposed of using the gpiod_put() function:
|
||||
|
||||
void gpiod_put(struct gpio_desc *desc)
|
||||
|
||||
It is strictly forbidden to use a descriptor after calling this function. The
|
||||
device-managed variant is, unsurprisingly:
|
||||
|
||||
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
||||
|
||||
|
||||
Using GPIOs
|
||||
===========
|
||||
|
||||
Setting Direction
|
||||
-----------------
|
||||
The first thing a driver must do with a GPIO is setting its direction. This is
|
||||
done by invoking one of the gpiod_direction_*() functions:
|
||||
|
||||
int gpiod_direction_input(struct gpio_desc *desc)
|
||||
int gpiod_direction_output(struct gpio_desc *desc, int value)
|
||||
|
||||
The return value is zero for success, else a negative errno. It should be
|
||||
checked, since the get/set calls don't return errors and since misconfiguration
|
||||
is possible. You should normally issue these calls from a task context. However,
|
||||
for spinlock-safe GPIOs it is OK to use them before tasking is enabled, as part
|
||||
of early board setup.
|
||||
|
||||
For output GPIOs, the value provided becomes the initial output value. This
|
||||
helps avoid signal glitching during system startup.
|
||||
|
||||
A driver can also query the current direction of a GPIO:
|
||||
|
||||
int gpiod_get_direction(const struct gpio_desc *desc)
|
||||
|
||||
This function will return either GPIOF_DIR_IN or GPIOF_DIR_OUT.
|
||||
|
||||
Be aware that there is no default direction for GPIOs. Therefore, **using a GPIO
|
||||
without setting its direction first is illegal and will result in undefined
|
||||
behavior!**
|
||||
|
||||
|
||||
Spinlock-Safe GPIO Access
|
||||
-------------------------
|
||||
Most GPIO controllers can be accessed with memory read/write instructions. Those
|
||||
don't need to sleep, and can safely be done from inside hard (non-threaded) IRQ
|
||||
handlers and similar contexts.
|
||||
|
||||
Use the following calls to access GPIOs from an atomic context:
|
||||
|
||||
int gpiod_get_value(const struct gpio_desc *desc);
|
||||
void gpiod_set_value(struct gpio_desc *desc, int value);
|
||||
|
||||
The values are boolean, zero for low, nonzero for high. When reading the value
|
||||
of an output pin, the value returned should be what's seen on the pin. That
|
||||
won't always match the specified output value, because of issues including
|
||||
open-drain signaling and output latencies.
|
||||
|
||||
The get/set calls do not return errors because "invalid GPIO" should have been
|
||||
reported earlier from gpiod_direction_*(). However, note that not all platforms
|
||||
can read the value of output pins; those that can't should always return zero.
|
||||
Also, using these calls for GPIOs that can't safely be accessed without sleeping
|
||||
(see below) is an error.
|
||||
|
||||
|
||||
GPIO Access That May Sleep
|
||||
--------------------------
|
||||
Some GPIO controllers must be accessed using message based buses like I2C or
|
||||
SPI. Commands to read or write those GPIO values require waiting to get to the
|
||||
head of a queue to transmit a command and get its response. This requires
|
||||
sleeping, which can't be done from inside IRQ handlers.
|
||||
|
||||
Platforms that support this type of GPIO distinguish them from other GPIOs by
|
||||
returning nonzero from this call:
|
||||
|
||||
int gpiod_cansleep(const struct gpio_desc *desc)
|
||||
|
||||
To access such GPIOs, a different set of accessors is defined:
|
||||
|
||||
int gpiod_get_value_cansleep(const struct gpio_desc *desc)
|
||||
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
|
||||
|
||||
Accessing such GPIOs requires a context which may sleep, for example a threaded
|
||||
IRQ handler, and those accessors must be used instead of spinlock-safe
|
||||
accessors without the cansleep() name suffix.
|
||||
|
||||
Other than the fact that these accessors might sleep, and will work on GPIOs
|
||||
that can't be accessed from hardIRQ handlers, these calls act the same as the
|
||||
spinlock-safe calls.
|
||||
|
||||
|
||||
Active-low State and Raw GPIO Values
|
||||
------------------------------------
|
||||
Device drivers like to manage the logical state of a GPIO, i.e. the value their
|
||||
device will actually receive, no matter what lies between it and the GPIO line.
|
||||
In some cases, it might make sense to control the actual GPIO line value. The
|
||||
following set of calls ignore the active-low property of a GPIO and work on the
|
||||
raw line value:
|
||||
|
||||
int gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
|
||||
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
|
||||
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
|
||||
|
||||
The active-low state of a GPIO can also be queried using the following call:
|
||||
|
||||
int gpiod_is_active_low(const struct gpio_desc *desc)
|
||||
|
||||
Note that these functions should only be used with great moderation ; a driver
|
||||
should not have to care about the physical line level.
|
||||
|
||||
GPIOs mapped to IRQs
|
||||
--------------------
|
||||
GPIO lines can quite often be used as IRQs. You can get the IRQ number
|
||||
corresponding to a given GPIO using the following call:
|
||||
|
||||
int gpiod_to_irq(const struct gpio_desc *desc)
|
||||
|
||||
It will return an IRQ number, or an negative errno code if the mapping can't be
|
||||
done (most likely because that particular GPIO cannot be used as IRQ). It is an
|
||||
unchecked error to use a GPIO that wasn't set up as an input using
|
||||
gpiod_direction_input(), or to use an IRQ number that didn't originally come
|
||||
from gpiod_to_irq(). gpiod_to_irq() is not allowed to sleep.
|
||||
|
||||
Non-error values returned from gpiod_to_irq() can be passed to request_irq() or
|
||||
free_irq(). They will often be stored into IRQ resources for platform devices,
|
||||
by the board-specific initialization code. Note that IRQ trigger options are
|
||||
part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup
|
||||
capabilities.
|
||||
|
||||
|
||||
Interacting With the Legacy GPIO Subsystem
|
||||
==========================================
|
||||
Many kernel subsystems still handle GPIOs using the legacy integer-based
|
||||
interface. Although it is strongly encouraged to upgrade them to the safer
|
||||
descriptor-based API, the following two functions allow you to convert a GPIO
|
||||
descriptor into the GPIO integer namespace and vice-versa:
|
||||
|
||||
int desc_to_gpio(const struct gpio_desc *desc)
|
||||
struct gpio_desc *gpio_to_desc(unsigned gpio)
|
||||
|
||||
The GPIO number returned by desc_to_gpio() can be safely used as long as the
|
||||
GPIO descriptor has not been freed. All the same, a GPIO number passed to
|
||||
gpio_to_desc() must have been properly acquired, and usage of the returned GPIO
|
||||
descriptor is only possible after the GPIO number has been released.
|
||||
|
||||
Freeing a GPIO obtained by one API with the other API is forbidden and an
|
||||
unchecked error.
|
75
Documentation/gpio/driver.txt
Normal file
75
Documentation/gpio/driver.txt
Normal file
@ -0,0 +1,75 @@
|
||||
GPIO Descriptor Driver Interface
|
||||
================================
|
||||
|
||||
This document serves as a guide for GPIO chip drivers writers. Note that it
|
||||
describes the new descriptor-based interface. For a description of the
|
||||
deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
|
||||
|
||||
Each GPIO controller driver needs to include the following header, which defines
|
||||
the structures used to define a GPIO driver:
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
|
||||
Internal Representation of GPIOs
|
||||
================================
|
||||
|
||||
Inside a GPIO driver, individual GPIOs are identified by their hardware number,
|
||||
which is a unique number between 0 and n, n being the number of GPIOs managed by
|
||||
the chip. This number is purely internal: the hardware number of a particular
|
||||
GPIO descriptor is never made visible outside of the driver.
|
||||
|
||||
On top of this internal number, each GPIO also need to have a global number in
|
||||
the integer GPIO namespace so that it can be used with the legacy GPIO
|
||||
interface. Each chip must thus have a "base" number (which can be automatically
|
||||
assigned), and for each GPIO the global number will be (base + hardware number).
|
||||
Although the integer representation is considered deprecated, it still has many
|
||||
users and thus needs to be maintained.
|
||||
|
||||
So for example one platform could use numbers 32-159 for GPIOs, with a
|
||||
controller defining 128 GPIOs at a "base" of 32 ; while another platform uses
|
||||
numbers 0..63 with one set of GPIO controllers, 64-79 with another type of GPIO
|
||||
controller, and on one particular board 80-95 with an FPGA. The numbers need not
|
||||
be contiguous; either of those platforms could also use numbers 2000-2063 to
|
||||
identify GPIOs in a bank of I2C GPIO expanders.
|
||||
|
||||
|
||||
Controller Drivers: gpio_chip
|
||||
=============================
|
||||
|
||||
In the gpiolib framework each GPIO controller is packaged as a "struct
|
||||
gpio_chip" (see linux/gpio/driver.h for its complete definition) with members
|
||||
common to each controller of that type:
|
||||
|
||||
- methods to establish GPIO direction
|
||||
- methods used to access GPIO values
|
||||
- method to return the IRQ number associated to a given GPIO
|
||||
- flag saying whether calls to its methods may sleep
|
||||
- optional debugfs dump method (showing extra state like pullup config)
|
||||
- optional base number (will be automatically assigned if omitted)
|
||||
- label for diagnostics and GPIOs mapping using platform data
|
||||
|
||||
The code implementing a gpio_chip should support multiple instances of the
|
||||
controller, possibly using the driver model. That code will configure each
|
||||
gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be rare;
|
||||
use gpiochip_remove() when it is unavoidable.
|
||||
|
||||
Most often a gpio_chip is part of an instance-specific structure with state not
|
||||
exposed by the GPIO interfaces, such as addressing, power management, and more.
|
||||
Chips such as codecs will have complex non-GPIO state.
|
||||
|
||||
Any debugfs dump method should normally ignore signals which haven't been
|
||||
requested as GPIOs. They can use gpiochip_is_requested(), which returns either
|
||||
NULL or the label associated with that GPIO when it was requested.
|
||||
|
||||
Locking IRQ usage
|
||||
-----------------
|
||||
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
|
||||
to mark the GPIO as being used as an IRQ:
|
||||
|
||||
int gpiod_lock_as_irq(struct gpio_desc *desc)
|
||||
|
||||
This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
|
||||
is released:
|
||||
|
||||
void gpiod_unlock_as_irq(struct gpio_desc *desc)
|
119
Documentation/gpio/gpio.txt
Normal file
119
Documentation/gpio/gpio.txt
Normal file
@ -0,0 +1,119 @@
|
||||
GPIO Interfaces
|
||||
===============
|
||||
|
||||
The documents in this directory give detailed instructions on how to access
|
||||
GPIOs in drivers, and how to write a driver for a device that provides GPIOs
|
||||
itself.
|
||||
|
||||
Due to the history of GPIO interfaces in the kernel, there are two different
|
||||
ways to obtain and use GPIOs:
|
||||
|
||||
- The descriptor-based interface is the preferred way to manipulate GPIOs,
|
||||
and is described by all the files in this directory excepted gpio-legacy.txt.
|
||||
- The legacy integer-based interface which is considered deprecated (but still
|
||||
usable for compatibility reasons) is documented in gpio-legacy.txt.
|
||||
|
||||
The remainder of this document applies to the new descriptor-based interface.
|
||||
gpio-legacy.txt contains the same information applied to the legacy
|
||||
integer-based interface.
|
||||
|
||||
|
||||
What is a GPIO?
|
||||
===============
|
||||
|
||||
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
|
||||
digital signal. They are provided from many kinds of chip, and are familiar
|
||||
to Linux developers working with embedded and custom hardware. Each GPIO
|
||||
represents a bit connected to a particular pin, or "ball" on Ball Grid Array
|
||||
(BGA) packages. Board schematics show which external hardware connects to
|
||||
which GPIOs. Drivers can be written generically, so that board setup code
|
||||
passes such pin configuration data to drivers.
|
||||
|
||||
System-on-Chip (SOC) processors heavily rely on GPIOs. In some cases, every
|
||||
non-dedicated pin can be configured as a GPIO; and most chips have at least
|
||||
several dozen of them. Programmable logic devices (like FPGAs) can easily
|
||||
provide GPIOs; multifunction chips like power managers, and audio codecs
|
||||
often have a few such pins to help with pin scarcity on SOCs; and there are
|
||||
also "GPIO Expander" chips that connect using the I2C or SPI serial buses.
|
||||
Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
|
||||
firmware knowing how they're used).
|
||||
|
||||
The exact capabilities of GPIOs vary between systems. Common options:
|
||||
|
||||
- Output values are writable (high=1, low=0). Some chips also have
|
||||
options about how that value is driven, so that for example only one
|
||||
value might be driven, supporting "wire-OR" and similar schemes for the
|
||||
other value (notably, "open drain" signaling).
|
||||
|
||||
- Input values are likewise readable (1, 0). Some chips support readback
|
||||
of pins configured as "output", which is very useful in such "wire-OR"
|
||||
cases (to support bidirectional signaling). GPIO controllers may have
|
||||
input de-glitch/debounce logic, sometimes with software controls.
|
||||
|
||||
- Inputs can often be used as IRQ signals, often edge triggered but
|
||||
sometimes level triggered. Such IRQs may be configurable as system
|
||||
wakeup events, to wake the system from a low power state.
|
||||
|
||||
- Usually a GPIO will be configurable as either input or output, as needed
|
||||
by different product boards; single direction ones exist too.
|
||||
|
||||
- Most GPIOs can be accessed while holding spinlocks, but those accessed
|
||||
through a serial bus normally can't. Some systems support both types.
|
||||
|
||||
On a given board each GPIO is used for one specific purpose like monitoring
|
||||
MMC/SD card insertion/removal, detecting card write-protect status, driving
|
||||
a LED, configuring a transceiver, bit-banging a serial bus, poking a hardware
|
||||
watchdog, sensing a switch, and so on.
|
||||
|
||||
|
||||
Common GPIO Properties
|
||||
======================
|
||||
|
||||
These properties are met through all the other documents of the GPIO interface
|
||||
and it is useful to understand them, especially if you need to define GPIO
|
||||
mappings.
|
||||
|
||||
Active-High and Active-Low
|
||||
--------------------------
|
||||
It is natural to assume that a GPIO is "active" when its output signal is 1
|
||||
("high"), and inactive when it is 0 ("low"). However in practice the signal of a
|
||||
GPIO may be inverted before is reaches its destination, or a device could decide
|
||||
to have different conventions about what "active" means. Such decisions should
|
||||
be transparent to device drivers, therefore it is possible to define a GPIO as
|
||||
being either active-high ("1" means "active", the default) or active-low ("0"
|
||||
means "active") so that drivers only need to worry about the logical signal and
|
||||
not about what happens at the line level.
|
||||
|
||||
Open Drain and Open Source
|
||||
--------------------------
|
||||
Sometimes shared signals need to use "open drain" (where only the low signal
|
||||
level is actually driven), or "open source" (where only the high signal level is
|
||||
driven) signaling. That term applies to CMOS transistors; "open collector" is
|
||||
used for TTL. A pullup or pulldown resistor causes the high or low signal level.
|
||||
This is sometimes called a "wire-AND"; or more practically, from the negative
|
||||
logic (low=true) perspective this is a "wire-OR".
|
||||
|
||||
One common example of an open drain signal is a shared active-low IRQ line.
|
||||
Also, bidirectional data bus signals sometimes use open drain signals.
|
||||
|
||||
Some GPIO controllers directly support open drain and open source outputs; many
|
||||
don't. When you need open drain signaling but your hardware doesn't directly
|
||||
support it, there's a common idiom you can use to emulate it with any GPIO pin
|
||||
that can be used as either an input or an output:
|
||||
|
||||
LOW: gpiod_direction_output(gpio, 0) ... this drives the signal and overrides
|
||||
the pullup.
|
||||
|
||||
HIGH: gpiod_direction_input(gpio) ... this turns off the output, so the pullup
|
||||
(or some other device) controls the signal.
|
||||
|
||||
The same logic can be applied to emulate open source signaling, by driving the
|
||||
high signal and configuring the GPIO as input for low. This open drain/open
|
||||
source emulation can be handled transparently by the GPIO framework.
|
||||
|
||||
If you are "driving" the signal high but gpiod_get_value(gpio) reports a low
|
||||
value (after the appropriate rise time passes), you know some other component is
|
||||
driving the shared signal low. That's not necessarily an error. As one common
|
||||
example, that's how I2C clocks are stretched: a slave that needs a slower clock
|
||||
delays the rising edge of SCK, and the I2C master adjusts its signaling rate
|
||||
accordingly.
|
155
Documentation/gpio/sysfs.txt
Normal file
155
Documentation/gpio/sysfs.txt
Normal file
@ -0,0 +1,155 @@
|
||||
GPIO Sysfs Interface for Userspace
|
||||
==================================
|
||||
|
||||
Platforms which use the "gpiolib" implementors framework may choose to
|
||||
configure a sysfs user interface to GPIOs. This is different from the
|
||||
debugfs interface, since it provides control over GPIO direction and
|
||||
value instead of just showing a gpio state summary. Plus, it could be
|
||||
present on production systems without debugging support.
|
||||
|
||||
Given appropriate hardware documentation for the system, userspace could
|
||||
know for example that GPIO #23 controls the write protect line used to
|
||||
protect boot loader segments in flash memory. System upgrade procedures
|
||||
may need to temporarily remove that protection, first importing a GPIO,
|
||||
then changing its output state, then updating the code before re-enabling
|
||||
the write protection. In normal use, GPIO #23 would never be touched,
|
||||
and the kernel would have no need to know about it.
|
||||
|
||||
Again depending on appropriate hardware documentation, on some systems
|
||||
userspace GPIO can be used to determine system configuration data that
|
||||
standard kernels won't know about. And for some tasks, simple userspace
|
||||
GPIO drivers could be all that the system really needs.
|
||||
|
||||
Note that standard kernel drivers exist for common "LEDs and Buttons"
|
||||
GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those
|
||||
instead of talking directly to the GPIOs; they integrate with kernel
|
||||
frameworks better than your userspace code could.
|
||||
|
||||
|
||||
Paths in Sysfs
|
||||
--------------
|
||||
There are three kinds of entry in /sys/class/gpio:
|
||||
|
||||
- Control interfaces used to get userspace control over GPIOs;
|
||||
|
||||
- GPIOs themselves; and
|
||||
|
||||
- GPIO controllers ("gpio_chip" instances).
|
||||
|
||||
That's in addition to standard files including the "device" symlink.
|
||||
|
||||
The control interfaces are write-only:
|
||||
|
||||
/sys/class/gpio/
|
||||
|
||||
"export" ... Userspace may ask the kernel to export control of
|
||||
a GPIO to userspace by writing its number to this file.
|
||||
|
||||
Example: "echo 19 > export" will create a "gpio19" node
|
||||
for GPIO #19, if that's not requested by kernel code.
|
||||
|
||||
"unexport" ... Reverses the effect of exporting to userspace.
|
||||
|
||||
Example: "echo 19 > unexport" will remove a "gpio19"
|
||||
node exported using the "export" file.
|
||||
|
||||
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
|
||||
and have the following read/write attributes:
|
||||
|
||||
/sys/class/gpio/gpioN/
|
||||
|
||||
"direction" ... reads as either "in" or "out". This value may
|
||||
normally be written. Writing as "out" defaults to
|
||||
initializing the value as low. To ensure glitch free
|
||||
operation, values "low" and "high" may be written to
|
||||
configure the GPIO as an output with that initial value.
|
||||
|
||||
Note that this attribute *will not exist* if the kernel
|
||||
doesn't support changing the direction of a GPIO, or
|
||||
it was exported by kernel code that didn't explicitly
|
||||
allow userspace to reconfigure this GPIO's direction.
|
||||
|
||||
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
|
||||
is configured as an output, this value may be written;
|
||||
any nonzero value is treated as high.
|
||||
|
||||
If the pin can be configured as interrupt-generating interrupt
|
||||
and if it has been configured to generate interrupts (see the
|
||||
description of "edge"), you can poll(2) on that file and
|
||||
poll(2) will return whenever the interrupt was triggered. If
|
||||
you use poll(2), set the events POLLPRI and POLLERR. If you
|
||||
use select(2), set the file descriptor in exceptfds. After
|
||||
poll(2) returns, either lseek(2) to the beginning of the sysfs
|
||||
file and read the new value or close the file and re-open it
|
||||
to read the value.
|
||||
|
||||
"edge" ... reads as either "none", "rising", "falling", or
|
||||
"both". Write these strings to select the signal edge(s)
|
||||
that will make poll(2) on the "value" file return.
|
||||
|
||||
This file exists only if the pin can be configured as an
|
||||
interrupt generating input pin.
|
||||
|
||||
"active_low" ... reads as either 0 (false) or 1 (true). Write
|
||||
any nonzero value to invert the value attribute both
|
||||
for reading and writing. Existing and subsequent
|
||||
poll(2) support configuration via the edge attribute
|
||||
for "rising" and "falling" edges will follow this
|
||||
setting.
|
||||
|
||||
GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
|
||||
controller implementing GPIOs starting at #42) and have the following
|
||||
read-only attributes:
|
||||
|
||||
/sys/class/gpio/gpiochipN/
|
||||
|
||||
"base" ... same as N, the first GPIO managed by this chip
|
||||
|
||||
"label" ... provided for diagnostics (not always unique)
|
||||
|
||||
"ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)
|
||||
|
||||
Board documentation should in most cases cover what GPIOs are used for
|
||||
what purposes. However, those numbers are not always stable; GPIOs on
|
||||
a daughtercard might be different depending on the base board being used,
|
||||
or other cards in the stack. In such cases, you may need to use the
|
||||
gpiochip nodes (possibly in conjunction with schematics) to determine
|
||||
the correct GPIO number to use for a given signal.
|
||||
|
||||
|
||||
Exporting from Kernel code
|
||||
--------------------------
|
||||
Kernel code can explicitly manage exports of GPIOs which have already been
|
||||
requested using gpio_request():
|
||||
|
||||
/* export the GPIO to userspace */
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
|
||||
/* reverse gpio_export() */
|
||||
void gpiod_unexport(struct gpio_desc *desc);
|
||||
|
||||
/* create a sysfs link to an exported GPIO node */
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
|
||||
/* change the polarity of a GPIO node in sysfs */
|
||||
int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value);
|
||||
|
||||
After a kernel driver requests a GPIO, it may only be made available in
|
||||
the sysfs interface by gpiod_export(). The driver can control whether the
|
||||
signal direction may change. This helps drivers prevent userspace code
|
||||
from accidentally clobbering important system state.
|
||||
|
||||
This explicit exporting can help with debugging (by making some kinds
|
||||
of experiments easier), or can provide an always-there interface that's
|
||||
suitable for documenting as part of a board support package.
|
||||
|
||||
After the GPIO has been exported, gpiod_export_link() allows creating
|
||||
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
|
||||
use this to provide the interface under their own device in sysfs with
|
||||
a descriptive name.
|
||||
|
||||
Drivers can use gpiod_sysfs_set_active_low() to hide GPIO line polarity
|
||||
differences between boards from user space. Polarity change can be done both
|
||||
before and after gpiod_export(), and previously enabled poll(2) support for
|
||||
either rising or falling edge will be reconfigured to follow this setting.
|
23
MAINTAINERS
23
MAINTAINERS
@ -1934,7 +1934,8 @@ S: Maintained
|
||||
F: drivers/gpio/gpio-bt8xx.c
|
||||
|
||||
BTRFS FILE SYSTEM
|
||||
M: Chris Mason <chris.mason@fusionio.com>
|
||||
M: Chris Mason <clm@fb.com>
|
||||
M: Josef Bacik <jbacik@fb.com>
|
||||
L: linux-btrfs@vger.kernel.org
|
||||
W: http://btrfs.wiki.kernel.org/
|
||||
Q: http://patchwork.kernel.org/project/linux-btrfs/list/
|
||||
@ -2142,6 +2143,11 @@ L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/usb/chipidea/
|
||||
|
||||
CHROME HARDWARE PLATFORM SUPPORT
|
||||
M: Olof Johansson <olof@lixom.net>
|
||||
S: Maintained
|
||||
F: drivers/platform/chrome/
|
||||
|
||||
CISCO VIC ETHERNET NIC DRIVER
|
||||
M: Christian Benvenuti <benve@cisco.com>
|
||||
M: Sujith Sankar <ssujith@cisco.com>
|
||||
@ -4044,6 +4050,12 @@ W: http://www.pharscape.org
|
||||
S: Maintained
|
||||
F: drivers/net/usb/hso.c
|
||||
|
||||
HSR NETWORK PROTOCOL
|
||||
M: Arvid Brodin <arvid.brodin@alten.se>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: net/hsr/
|
||||
|
||||
HTCPEN TOUCHSCREEN DRIVER
|
||||
M: Pau Oliva Fora <pof@eslack.org>
|
||||
L: linux-input@vger.kernel.org
|
||||
@ -5256,7 +5268,7 @@ S: Maintained
|
||||
F: Documentation/lockdep*.txt
|
||||
F: Documentation/lockstat.txt
|
||||
F: include/linux/lockdep.h
|
||||
F: kernel/lockdep*
|
||||
F: kernel/locking/
|
||||
|
||||
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
|
||||
M: "Richard Russon (FlatCap)" <ldm@flatcap.org>
|
||||
@ -5968,10 +5980,10 @@ F: drivers/nfc/
|
||||
F: include/linux/platform_data/pn544.h
|
||||
|
||||
NFS, SUNRPC, AND LOCKD CLIENTS
|
||||
M: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
M: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||
L: linux-nfs@vger.kernel.org
|
||||
W: http://client.linux-nfs.org
|
||||
T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git
|
||||
T: git git://git.linux-nfs.org/projects/trondmy/linux-nfs.git
|
||||
S: Maintained
|
||||
F: fs/lockd/
|
||||
F: fs/nfs/
|
||||
@ -6238,8 +6250,8 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
|
||||
M: Rob Herring <rob.herring@calxeda.com>
|
||||
M: Pawel Moll <pawel.moll@arm.com>
|
||||
M: Mark Rutland <mark.rutland@arm.com>
|
||||
M: Stephen Warren <swarren@wwwdotorg.org>
|
||||
M: Ian Campbell <ijc+devicetree@hellion.org.uk>
|
||||
M: Kumar Gala <galak@codeaurora.org>
|
||||
L: devicetree@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/
|
||||
@ -7380,7 +7392,6 @@ S: Maintained
|
||||
F: kernel/sched/
|
||||
F: include/linux/sched.h
|
||||
F: include/uapi/linux/sched.h
|
||||
F: kernel/wait.c
|
||||
F: include/linux/wait.h
|
||||
|
||||
SCORE ARCHITECTURE
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 13
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = One Giant Leap for Frogkind
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -7,11 +7,11 @@
|
||||
*/
|
||||
/dts-v1/;
|
||||
|
||||
#include "omap34xx.dtsi"
|
||||
#include "am3517.dtsi"
|
||||
|
||||
/ {
|
||||
model = "TI AM3517 EVM (AM3517/05)";
|
||||
compatible = "ti,am3517-evm", "ti,omap3";
|
||||
model = "TI AM3517 EVM (AM3517/05 TMDSEVM3517)";
|
||||
compatible = "ti,am3517-evm", "ti,am3517", "ti,omap3";
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
|
63
arch/arm/boot/dts/am3517.dtsi
Normal file
63
arch/arm/boot/dts/am3517.dtsi
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Device Tree Source for am3517 SoC
|
||||
*
|
||||
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include "omap3.dtsi"
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
serial3 = &uart4;
|
||||
};
|
||||
|
||||
ocp {
|
||||
am35x_otg_hs: am35x_otg_hs@5c040000 {
|
||||
compatible = "ti,omap3-musb";
|
||||
ti,hwmods = "am35x_otg_hs";
|
||||
status = "disabled";
|
||||
reg = <0x5c040000 0x1000>;
|
||||
interrupts = <71>;
|
||||
interrupt-names = "mc";
|
||||
};
|
||||
|
||||
davinci_emac: ethernet@0x5c000000 {
|
||||
compatible = "ti,am3517-emac";
|
||||
ti,hwmods = "davinci_emac";
|
||||
status = "disabled";
|
||||
reg = <0x5c000000 0x30000>;
|
||||
interrupts = <67 68 69 70>;
|
||||
ti,davinci-ctrl-reg-offset = <0x10000>;
|
||||
ti,davinci-ctrl-mod-reg-offset = <0>;
|
||||
ti,davinci-ctrl-ram-offset = <0x20000>;
|
||||
ti,davinci-ctrl-ram-size = <0x2000>;
|
||||
ti,davinci-rmii-en = /bits/ 8 <1>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
||||
davinci_mdio: ethernet@0x5c030000 {
|
||||
compatible = "ti,davinci_mdio";
|
||||
ti,hwmods = "davinci_mdio";
|
||||
status = "disabled";
|
||||
reg = <0x5c030000 0x1000>;
|
||||
bus_freq = <1000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
uart4: serial@4809e000 {
|
||||
compatible = "ti,omap3-uart";
|
||||
ti,hwmods = "uart4";
|
||||
status = "disabled";
|
||||
reg = <0x4809e000 0x400>;
|
||||
interrupts = <84>;
|
||||
dmas = <&sdma 55 &sdma 54>;
|
||||
dma-names = "tx", "rx";
|
||||
clock-frequency = <48000000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -9,7 +9,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "omap34xx.dtsi"
|
||||
#include "omap34xx-hs.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Nokia N900";
|
||||
|
@ -8,7 +8,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "omap36xx.dtsi"
|
||||
#include "omap36xx-hs.dtsi"
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
|
16
arch/arm/boot/dts/omap34xx-hs.dtsi
Normal file
16
arch/arm/boot/dts/omap34xx-hs.dtsi
Normal file
@ -0,0 +1,16 @@
|
||||
/* Disabled modules for secure omaps */
|
||||
|
||||
#include "omap34xx.dtsi"
|
||||
|
||||
/* Secure omaps have some devices inaccessible depending on the firmware */
|
||||
&aes {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sham {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&timer12 {
|
||||
status = "disabled";
|
||||
};
|
16
arch/arm/boot/dts/omap36xx-hs.dtsi
Normal file
16
arch/arm/boot/dts/omap36xx-hs.dtsi
Normal file
@ -0,0 +1,16 @@
|
||||
/* Disabled modules for secure omaps */
|
||||
|
||||
#include "omap36xx.dtsi"
|
||||
|
||||
/* Secure omaps have some devices inaccessible depending on the firmware */
|
||||
&aes {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sham {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&timer12 {
|
||||
status = "disabled";
|
||||
};
|
@ -61,7 +61,7 @@ extern void __pgd_error(const char *file, int line, pgd_t);
|
||||
* mapping to be mapped at. This is particularly important for
|
||||
* non-high vector CPUs.
|
||||
*/
|
||||
#define FIRST_USER_ADDRESS PAGE_SIZE
|
||||
#define FIRST_USER_ADDRESS (PAGE_SIZE * 2)
|
||||
|
||||
/*
|
||||
* Use TASK_SIZE as the ceiling argument for free_pgtables() and
|
||||
|
@ -14,11 +14,12 @@
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/fncpy.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
extern void relocate_new_kernel(void);
|
||||
extern const unsigned int relocate_new_kernel_size;
|
||||
|
||||
extern unsigned long kexec_start_address;
|
||||
@ -142,6 +143,8 @@ void machine_kexec(struct kimage *image)
|
||||
{
|
||||
unsigned long page_list;
|
||||
unsigned long reboot_code_buffer_phys;
|
||||
unsigned long reboot_entry = (unsigned long)relocate_new_kernel;
|
||||
unsigned long reboot_entry_phys;
|
||||
void *reboot_code_buffer;
|
||||
|
||||
/*
|
||||
@ -168,16 +171,16 @@ void machine_kexec(struct kimage *image)
|
||||
|
||||
|
||||
/* copy our kernel relocation code to the control code page */
|
||||
memcpy(reboot_code_buffer,
|
||||
relocate_new_kernel, relocate_new_kernel_size);
|
||||
reboot_entry = fncpy(reboot_code_buffer,
|
||||
reboot_entry,
|
||||
relocate_new_kernel_size);
|
||||
reboot_entry_phys = (unsigned long)reboot_entry +
|
||||
(reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
|
||||
|
||||
|
||||
flush_icache_range((unsigned long) reboot_code_buffer,
|
||||
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
|
||||
printk(KERN_INFO "Bye!\n");
|
||||
|
||||
if (kexec_reinit)
|
||||
kexec_reinit();
|
||||
|
||||
soft_restart(reboot_code_buffer_phys);
|
||||
soft_restart(reboot_entry_phys);
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
* relocate_kernel.S - put the kernel image in place to boot
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/kexec.h>
|
||||
|
||||
.globl relocate_new_kernel
|
||||
relocate_new_kernel:
|
||||
.align 3 /* not needed for this code, but keeps fncpy() happy */
|
||||
|
||||
ENTRY(relocate_new_kernel)
|
||||
|
||||
ldr r0,kexec_indirection_page
|
||||
ldr r1,kexec_start_address
|
||||
@ -79,6 +81,8 @@ kexec_mach_type:
|
||||
kexec_boot_atags:
|
||||
.long 0x0
|
||||
|
||||
ENDPROC(relocate_new_kernel)
|
||||
|
||||
relocate_new_kernel_end:
|
||||
|
||||
.globl relocate_new_kernel_size
|
||||
|
@ -30,6 +30,27 @@
|
||||
* snippets.
|
||||
*/
|
||||
|
||||
/*
|
||||
* In CPU_THUMBONLY case kernel arm opcodes are not allowed.
|
||||
* Note in this case codes skips those instructions but it uses .org
|
||||
* directive to keep correct layout of sigreturn_codes array.
|
||||
*/
|
||||
#ifndef CONFIG_CPU_THUMBONLY
|
||||
#define ARM_OK(code...) code
|
||||
#else
|
||||
#define ARM_OK(code...)
|
||||
#endif
|
||||
|
||||
.macro arm_slot n
|
||||
.org sigreturn_codes + 12 * (\n)
|
||||
ARM_OK( .arm )
|
||||
.endm
|
||||
|
||||
.macro thumb_slot n
|
||||
.org sigreturn_codes + 12 * (\n) + 8
|
||||
.thumb
|
||||
.endm
|
||||
|
||||
#if __LINUX_ARM_ARCH__ <= 4
|
||||
/*
|
||||
* Note we manually set minimally required arch that supports
|
||||
@ -45,26 +66,27 @@
|
||||
.global sigreturn_codes
|
||||
.type sigreturn_codes, #object
|
||||
|
||||
.arm
|
||||
.align
|
||||
|
||||
sigreturn_codes:
|
||||
|
||||
/* ARM sigreturn syscall code snippet */
|
||||
mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
|
||||
swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)
|
||||
arm_slot 0
|
||||
ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) )
|
||||
ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
|
||||
|
||||
/* Thumb sigreturn syscall code snippet */
|
||||
.thumb
|
||||
thumb_slot 0
|
||||
movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE)
|
||||
swi #0
|
||||
|
||||
/* ARM sigreturn_rt syscall code snippet */
|
||||
.arm
|
||||
mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
|
||||
swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)
|
||||
arm_slot 1
|
||||
ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) )
|
||||
ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) )
|
||||
|
||||
/* Thumb sigreturn_rt syscall code snippet */
|
||||
.thumb
|
||||
thumb_slot 1
|
||||
movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE)
|
||||
swi #0
|
||||
|
||||
@ -74,7 +96,7 @@ sigreturn_codes:
|
||||
* it is thumb case or not, so we need additional
|
||||
* word after real last entry.
|
||||
*/
|
||||
.arm
|
||||
arm_slot 2
|
||||
.space 4
|
||||
|
||||
.size sigreturn_codes, . - sigreturn_codes
|
||||
|
@ -40,6 +40,7 @@ ENTRY(__loop_const_udelay) @ 0 <= r0 <= 0x7fffff06
|
||||
/*
|
||||
* loops = r0 * HZ * loops_per_jiffy / 1000000
|
||||
*/
|
||||
.align 3
|
||||
|
||||
@ Delay routine
|
||||
ENTRY(__loop_delay)
|
||||
|
@ -174,7 +174,6 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
|
||||
static struct clock_event_device clkevt = {
|
||||
.name = "at91_tick",
|
||||
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 32,
|
||||
.rating = 150,
|
||||
.set_next_event = clkevt32k_next_event,
|
||||
.set_mode = clkevt32k_mode,
|
||||
@ -265,11 +264,9 @@ void __init at91rm9200_timer_init(void)
|
||||
at91_st_write(AT91_ST_RTMR, 1);
|
||||
|
||||
/* Setup timer clockevent, with minimum of two ticks (important!!) */
|
||||
clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
|
||||
clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
|
||||
clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
|
||||
clkevt.cpumask = cpumask_of(0);
|
||||
clockevents_register_device(&clkevt);
|
||||
clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
|
||||
2, AT91_ST_ALMV);
|
||||
|
||||
/* register clocksource */
|
||||
clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <video/vga.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
@ -196,6 +197,8 @@ void __init footbridge_map_io(void)
|
||||
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
|
||||
pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
|
||||
}
|
||||
|
||||
vga_base = PCIMEM_BASE;
|
||||
}
|
||||
|
||||
void footbridge_restart(enum reboot_mode mode, const char *cmd)
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <video/vga.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
@ -291,7 +290,6 @@ void __init dc21285_preinit(void)
|
||||
int cfn_mode;
|
||||
|
||||
pcibios_min_mem = 0x81000000;
|
||||
vga_base = PCIMEM_BASE;
|
||||
|
||||
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
|
||||
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
|
||||
|
@ -30,21 +30,24 @@ static const struct {
|
||||
const char *name;
|
||||
const char *trigger;
|
||||
} ebsa285_leds[] = {
|
||||
{ "ebsa285:amber", "heartbeat", },
|
||||
{ "ebsa285:green", "cpu0", },
|
||||
{ "ebsa285:amber", "cpu0", },
|
||||
{ "ebsa285:green", "heartbeat", },
|
||||
{ "ebsa285:red",},
|
||||
};
|
||||
|
||||
static unsigned char hw_led_state;
|
||||
|
||||
static void ebsa285_led_set(struct led_classdev *cdev,
|
||||
enum led_brightness b)
|
||||
{
|
||||
struct ebsa285_led *led = container_of(cdev,
|
||||
struct ebsa285_led, cdev);
|
||||
|
||||
if (b != LED_OFF)
|
||||
*XBUS_LEDS |= led->mask;
|
||||
if (b == LED_OFF)
|
||||
hw_led_state |= led->mask;
|
||||
else
|
||||
*XBUS_LEDS &= ~led->mask;
|
||||
hw_led_state &= ~led->mask;
|
||||
*XBUS_LEDS = hw_led_state;
|
||||
}
|
||||
|
||||
static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
|
||||
@ -52,18 +55,19 @@ static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
|
||||
struct ebsa285_led *led = container_of(cdev,
|
||||
struct ebsa285_led, cdev);
|
||||
|
||||
return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF;
|
||||
return hw_led_state & led->mask ? LED_OFF : LED_FULL;
|
||||
}
|
||||
|
||||
static int __init ebsa285_leds_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (machine_is_ebsa285())
|
||||
if (!machine_is_ebsa285())
|
||||
return -ENODEV;
|
||||
|
||||
/* 3 LEDS All ON */
|
||||
*XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
|
||||
/* 3 LEDS all off */
|
||||
hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
|
||||
*XBUS_LEDS = hw_led_state;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
|
||||
struct ebsa285_led *led;
|
||||
|
@ -131,6 +131,24 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
|
||||
.dt_compat = omap3_gp_boards_compat,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
static const char *am3517_boards_compat[] __initdata = {
|
||||
"ti,am3517",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
|
||||
.reserve = omap_reserve,
|
||||
.map_io = omap3_map_io,
|
||||
.init_early = am35xx_init_early,
|
||||
.init_irq = omap_intc_of_init,
|
||||
.handle_irq = omap3_intc_handle_irq,
|
||||
.init_machine = omap_generic_init,
|
||||
.init_late = omap3_init_late,
|
||||
.init_time = omap3_gptimer_timer_init,
|
||||
.dt_compat = am3517_boards_compat,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_AM33XX
|
||||
|
@ -2326,38 +2326,80 @@ static int _shutdown(struct omap_hwmod *oh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_dev_find_hwmod(struct device_node *np,
|
||||
struct omap_hwmod *oh)
|
||||
{
|
||||
int count, i, res;
|
||||
const char *p;
|
||||
|
||||
count = of_property_count_strings(np, "ti,hwmods");
|
||||
if (count < 1)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
res = of_property_read_string_index(np, "ti,hwmods",
|
||||
i, &p);
|
||||
if (res)
|
||||
continue;
|
||||
if (!strcmp(p, oh->name)) {
|
||||
pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
|
||||
np->name, i, oh->name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_dev_hwmod_lookup - look up needed hwmod from dt blob
|
||||
* @np: struct device_node *
|
||||
* @oh: struct omap_hwmod *
|
||||
* @index: index of the entry found
|
||||
* @found: struct device_node * found or NULL
|
||||
*
|
||||
* Parse the dt blob and find out needed hwmod. Recursive function is
|
||||
* implemented to take care hierarchical dt blob parsing.
|
||||
* Return: The device node on success or NULL on failure.
|
||||
* Return: Returns 0 on success, -ENODEV when not found.
|
||||
*/
|
||||
static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
|
||||
struct omap_hwmod *oh)
|
||||
static int of_dev_hwmod_lookup(struct device_node *np,
|
||||
struct omap_hwmod *oh,
|
||||
int *index,
|
||||
struct device_node **found)
|
||||
{
|
||||
struct device_node *np0 = NULL, *np1 = NULL;
|
||||
const char *p;
|
||||
struct device_node *np0 = NULL;
|
||||
int res;
|
||||
|
||||
res = of_dev_find_hwmod(np, oh);
|
||||
if (res >= 0) {
|
||||
*found = np;
|
||||
*index = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for_each_child_of_node(np, np0) {
|
||||
if (of_find_property(np0, "ti,hwmods", NULL)) {
|
||||
p = of_get_property(np0, "ti,hwmods", NULL);
|
||||
if (!strcmp(p, oh->name))
|
||||
return np0;
|
||||
np1 = of_dev_hwmod_lookup(np0, oh);
|
||||
if (np1)
|
||||
return np1;
|
||||
struct device_node *fc;
|
||||
int i;
|
||||
|
||||
res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
|
||||
if (res == 0) {
|
||||
*found = fc;
|
||||
*index = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
*found = NULL;
|
||||
*index = 0;
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* _init_mpu_rt_base - populate the virtual address for a hwmod
|
||||
* @oh: struct omap_hwmod * to locate the virtual address
|
||||
* @data: (unused, caller should pass NULL)
|
||||
* @index: index of the reg entry iospace in device tree
|
||||
* @np: struct device_node * of the IP block's device node in the DT data
|
||||
*
|
||||
* Cache the virtual address used by the MPU to access this IP block's
|
||||
@ -2368,7 +2410,7 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
|
||||
* -ENXIO on absent or invalid register target address space.
|
||||
*/
|
||||
static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
||||
struct device_node *np)
|
||||
int index, struct device_node *np)
|
||||
{
|
||||
struct omap_hwmod_addr_space *mem;
|
||||
void __iomem *va_start = NULL;
|
||||
@ -2390,13 +2432,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
||||
if (!np)
|
||||
return -ENXIO;
|
||||
|
||||
va_start = of_iomap(np, oh->mpu_rt_idx);
|
||||
va_start = of_iomap(np, index + oh->mpu_rt_idx);
|
||||
} else {
|
||||
va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
|
||||
}
|
||||
|
||||
if (!va_start) {
|
||||
pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
|
||||
if (mem)
|
||||
pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
|
||||
else
|
||||
pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
|
||||
oh->name, index, np->full_name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -2422,17 +2468,29 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
||||
*/
|
||||
static int __init _init(struct omap_hwmod *oh, void *data)
|
||||
{
|
||||
int r;
|
||||
int r, index;
|
||||
struct device_node *np = NULL;
|
||||
|
||||
if (oh->_state != _HWMOD_STATE_REGISTERED)
|
||||
return 0;
|
||||
|
||||
if (of_have_populated_dt())
|
||||
np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
|
||||
if (of_have_populated_dt()) {
|
||||
struct device_node *bus;
|
||||
|
||||
bus = of_find_node_by_name(NULL, "ocp");
|
||||
if (!bus)
|
||||
return -ENODEV;
|
||||
|
||||
r = of_dev_hwmod_lookup(bus, oh, &index, &np);
|
||||
if (r)
|
||||
pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
|
||||
else if (np && index)
|
||||
pr_warn("omap_hwmod: %s using broken dt data from %s\n",
|
||||
oh->name, np->name);
|
||||
}
|
||||
|
||||
if (oh->class->sysc) {
|
||||
r = _init_mpu_rt_base(oh, NULL, np);
|
||||
r = _init_mpu_rt_base(oh, NULL, index, np);
|
||||
if (r < 0) {
|
||||
WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
|
||||
oh->name);
|
||||
|
@ -209,13 +209,3 @@ void __init tegra_init_fuse(void)
|
||||
tegra_sku_id, tegra_cpu_process_id,
|
||||
tegra_core_process_id);
|
||||
}
|
||||
|
||||
unsigned long long tegra_chip_uid(void)
|
||||
{
|
||||
unsigned long long lo, hi;
|
||||
|
||||
lo = tegra_fuse_readl(FUSE_UID_LOW);
|
||||
hi = tegra_fuse_readl(FUSE_UID_HIGH);
|
||||
return (hi << 32ull) | lo;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_chip_uid);
|
||||
|
@ -9,6 +9,7 @@
|
||||
*
|
||||
* DMA uncached mapping support.
|
||||
*/
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
@ -162,6 +163,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
|
||||
u64 mask = (u64)DMA_BIT_MASK(32);
|
||||
|
||||
if (dev) {
|
||||
unsigned long max_dma_pfn;
|
||||
|
||||
mask = dev->coherent_dma_mask;
|
||||
|
||||
/*
|
||||
@ -173,6 +176,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
|
||||
|
||||
/*
|
||||
* If the mask allows for more memory than we can address,
|
||||
* and we actually have that much memory, then fail the
|
||||
@ -180,7 +185,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
|
||||
*/
|
||||
if (sizeof(mask) != sizeof(dma_addr_t) &&
|
||||
mask > (dma_addr_t)~0 &&
|
||||
dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) {
|
||||
dma_to_pfn(dev, ~0) > max_dma_pfn) {
|
||||
dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
|
||||
mask);
|
||||
dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
|
||||
@ -192,7 +197,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
|
||||
* fits within the allowable addresses which we can
|
||||
* allocate.
|
||||
*/
|
||||
if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit) {
|
||||
if (dma_to_pfn(dev, mask) < max_dma_pfn) {
|
||||
dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
|
||||
mask,
|
||||
dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
|
||||
|
@ -146,7 +146,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
||||
|
||||
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
|
||||
info.length = len;
|
||||
info.low_limit = PAGE_SIZE;
|
||||
info.low_limit = FIRST_USER_ADDRESS;
|
||||
info.high_limit = mm->mmap_base;
|
||||
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
|
||||
info.align_offset = pgoff << PAGE_SHIFT;
|
||||
|
@ -87,7 +87,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
init_pud = pud_offset(init_pgd, 0);
|
||||
init_pmd = pmd_offset(init_pud, 0);
|
||||
init_pte = pte_offset_map(init_pmd, 0);
|
||||
set_pte_ext(new_pte, *init_pte, 0);
|
||||
set_pte_ext(new_pte + 0, init_pte[0], 0);
|
||||
set_pte_ext(new_pte + 1, init_pte[1], 0);
|
||||
pte_unmap(init_pte);
|
||||
pte_unmap(new_pte);
|
||||
}
|
||||
|
@ -25,8 +25,9 @@ struct xen_p2m_entry {
|
||||
struct rb_node rbnode_phys;
|
||||
};
|
||||
|
||||
rwlock_t p2m_lock;
|
||||
static rwlock_t p2m_lock;
|
||||
struct rb_root phys_to_mach = RB_ROOT;
|
||||
EXPORT_SYMBOL_GPL(phys_to_mach);
|
||||
static struct rb_root mach_to_phys = RB_ROOT;
|
||||
|
||||
static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new)
|
||||
@ -200,7 +201,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__set_phys_to_machine);
|
||||
|
||||
int p2m_init(void)
|
||||
static int p2m_init(void)
|
||||
{
|
||||
rwlock_init(&p2m_lock);
|
||||
return 0;
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/memreserve/ 0x80000000 0x00010000;
|
||||
|
||||
/ {
|
||||
model = "Foundation-v8A";
|
||||
compatible = "arm,foundation-aarch64", "arm,vexpress";
|
||||
|
@ -56,6 +56,9 @@ static inline void arch_local_irq_disable(void)
|
||||
#define local_fiq_enable() asm("msr daifclr, #1" : : : "memory")
|
||||
#define local_fiq_disable() asm("msr daifset, #1" : : : "memory")
|
||||
|
||||
#define local_async_enable() asm("msr daifclr, #4" : : : "memory")
|
||||
#define local_async_disable() asm("msr daifset, #4" : : : "memory")
|
||||
|
||||
/*
|
||||
* Save the current interrupt enable state.
|
||||
*/
|
||||
|
@ -25,10 +25,11 @@
|
||||
* Software defined PTE bits definition.
|
||||
*/
|
||||
#define PTE_VALID (_AT(pteval_t, 1) << 0)
|
||||
#define PTE_PROT_NONE (_AT(pteval_t, 1) << 2) /* only when !PTE_VALID */
|
||||
#define PTE_FILE (_AT(pteval_t, 1) << 3) /* only when !pte_present() */
|
||||
#define PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !pte_present() */
|
||||
#define PTE_DIRTY (_AT(pteval_t, 1) << 55)
|
||||
#define PTE_SPECIAL (_AT(pteval_t, 1) << 56)
|
||||
/* bit 57 for PMD_SECT_SPLITTING */
|
||||
#define PTE_PROT_NONE (_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
|
||||
|
||||
/*
|
||||
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
|
||||
@ -254,7 +255,7 @@ static inline int has_transparent_hugepage(void)
|
||||
#define pgprot_noncached(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
|
||||
#define pgprot_writecombine(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE))
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define pgprot_dmacoherent(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||
@ -357,18 +358,20 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
/*
|
||||
* Encode and decode a swap entry:
|
||||
* bits 0, 2: present (must both be zero)
|
||||
* bit 3: PTE_FILE
|
||||
* bits 4-8: swap type
|
||||
* bits 9-63: swap offset
|
||||
* bits 0-1: present (must be zero)
|
||||
* bit 2: PTE_FILE
|
||||
* bits 3-8: swap type
|
||||
* bits 9-57: swap offset
|
||||
*/
|
||||
#define __SWP_TYPE_SHIFT 4
|
||||
#define __SWP_TYPE_SHIFT 3
|
||||
#define __SWP_TYPE_BITS 6
|
||||
#define __SWP_OFFSET_BITS 49
|
||||
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
|
||||
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
|
||||
#define __SWP_OFFSET_MASK ((1UL << __SWP_OFFSET_BITS) - 1)
|
||||
|
||||
#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
|
||||
#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
|
||||
#define __swp_offset(x) (((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK)
|
||||
#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
|
||||
|
||||
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
||||
@ -382,15 +385,15 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
|
||||
|
||||
/*
|
||||
* Encode and decode a file entry:
|
||||
* bits 0, 2: present (must both be zero)
|
||||
* bit 3: PTE_FILE
|
||||
* bits 4-63: file offset / PAGE_SIZE
|
||||
* bits 0-1: present (must be zero)
|
||||
* bit 2: PTE_FILE
|
||||
* bits 3-57: file offset / PAGE_SIZE
|
||||
*/
|
||||
#define pte_file(pte) (pte_val(pte) & PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 4)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE)
|
||||
#define pte_to_pgoff(x) (pte_val(x) >> 3)
|
||||
#define pgoff_to_pte(x) __pte(((x) << 3) | PTE_FILE)
|
||||
|
||||
#define PTE_FILE_MAX_BITS 60
|
||||
#define PTE_FILE_MAX_BITS 55
|
||||
|
||||
extern int kern_addr_valid(unsigned long addr);
|
||||
|
||||
|
@ -248,7 +248,8 @@ static int brk_handler(unsigned long addr, unsigned int esr,
|
||||
int aarch32_break_handler(struct pt_regs *regs)
|
||||
{
|
||||
siginfo_t info;
|
||||
unsigned int instr;
|
||||
u32 arm_instr;
|
||||
u16 thumb_instr;
|
||||
bool bp = false;
|
||||
void __user *pc = (void __user *)instruction_pointer(regs);
|
||||
|
||||
@ -257,18 +258,21 @@ int aarch32_break_handler(struct pt_regs *regs)
|
||||
|
||||
if (compat_thumb_mode(regs)) {
|
||||
/* get 16-bit Thumb instruction */
|
||||
get_user(instr, (u16 __user *)pc);
|
||||
if (instr == AARCH32_BREAK_THUMB2_LO) {
|
||||
get_user(thumb_instr, (u16 __user *)pc);
|
||||
thumb_instr = le16_to_cpu(thumb_instr);
|
||||
if (thumb_instr == AARCH32_BREAK_THUMB2_LO) {
|
||||
/* get second half of 32-bit Thumb-2 instruction */
|
||||
get_user(instr, (u16 __user *)(pc + 2));
|
||||
bp = instr == AARCH32_BREAK_THUMB2_HI;
|
||||
get_user(thumb_instr, (u16 __user *)(pc + 2));
|
||||
thumb_instr = le16_to_cpu(thumb_instr);
|
||||
bp = thumb_instr == AARCH32_BREAK_THUMB2_HI;
|
||||
} else {
|
||||
bp = instr == AARCH32_BREAK_THUMB;
|
||||
bp = thumb_instr == AARCH32_BREAK_THUMB;
|
||||
}
|
||||
} else {
|
||||
/* 32-bit ARM instruction */
|
||||
get_user(instr, (u32 __user *)pc);
|
||||
bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
|
||||
get_user(arm_instr, (u32 __user *)pc);
|
||||
arm_instr = le32_to_cpu(arm_instr);
|
||||
bp = (arm_instr & ~0xf0000000) == AARCH32_BREAK_ARM;
|
||||
}
|
||||
|
||||
if (!bp)
|
||||
|
@ -309,15 +309,12 @@ el1_irq:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
|
||||
irq_handler
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
get_thread_info tsk
|
||||
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
|
||||
add w0, w24, #1 // increment it
|
||||
str w0, [tsk, #TI_PREEMPT]
|
||||
#endif
|
||||
irq_handler
|
||||
#ifdef CONFIG_PREEMPT
|
||||
str w24, [tsk, #TI_PREEMPT] // restore preempt count
|
||||
ldr w24, [tsk, #TI_PREEMPT] // restore preempt count
|
||||
cbnz w24, 1f // preempt count != 0
|
||||
ldr x0, [tsk, #TI_FLAGS] // get flags
|
||||
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
|
||||
@ -507,22 +504,10 @@ el0_irq_naked:
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
get_thread_info tsk
|
||||
#ifdef CONFIG_PREEMPT
|
||||
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
|
||||
add w23, w24, #1 // increment it
|
||||
str w23, [tsk, #TI_PREEMPT]
|
||||
#endif
|
||||
|
||||
irq_handler
|
||||
#ifdef CONFIG_PREEMPT
|
||||
ldr w0, [tsk, #TI_PREEMPT]
|
||||
str w24, [tsk, #TI_PREEMPT]
|
||||
cmp w0, w23
|
||||
b.eq 1f
|
||||
mov x1, #0
|
||||
str x1, [x1] // BUG
|
||||
1:
|
||||
#endif
|
||||
get_thread_info tsk
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_on
|
||||
#endif
|
||||
|
@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target,
|
||||
|
||||
for (i = 0; i < num_regs; ++i) {
|
||||
unsigned int idx = start + i;
|
||||
void *reg;
|
||||
compat_ulong_t reg;
|
||||
|
||||
switch (idx) {
|
||||
case 15:
|
||||
reg = (void *)&task_pt_regs(target)->pc;
|
||||
reg = task_pt_regs(target)->pc;
|
||||
break;
|
||||
case 16:
|
||||
reg = (void *)&task_pt_regs(target)->pstate;
|
||||
reg = task_pt_regs(target)->pstate;
|
||||
break;
|
||||
case 17:
|
||||
reg = (void *)&task_pt_regs(target)->orig_x0;
|
||||
reg = task_pt_regs(target)->orig_x0;
|
||||
break;
|
||||
default:
|
||||
reg = (void *)&task_pt_regs(target)->regs[idx];
|
||||
reg = task_pt_regs(target)->regs[idx];
|
||||
}
|
||||
|
||||
ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
|
||||
|
||||
ret = copy_to_user(ubuf, ®, sizeof(reg));
|
||||
if (ret)
|
||||
break;
|
||||
else
|
||||
ubuf += sizeof(compat_ulong_t);
|
||||
|
||||
ubuf += sizeof(reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target,
|
||||
|
||||
for (i = 0; i < num_regs; ++i) {
|
||||
unsigned int idx = start + i;
|
||||
void *reg;
|
||||
compat_ulong_t reg;
|
||||
|
||||
ret = copy_from_user(®, ubuf, sizeof(reg));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ubuf += sizeof(reg);
|
||||
|
||||
switch (idx) {
|
||||
case 15:
|
||||
reg = (void *)&newregs.pc;
|
||||
newregs.pc = reg;
|
||||
break;
|
||||
case 16:
|
||||
reg = (void *)&newregs.pstate;
|
||||
newregs.pstate = reg;
|
||||
break;
|
||||
case 17:
|
||||
reg = (void *)&newregs.orig_x0;
|
||||
newregs.orig_x0 = reg;
|
||||
break;
|
||||
default:
|
||||
reg = (void *)&newregs.regs[idx];
|
||||
newregs.regs[idx] = reg;
|
||||
}
|
||||
|
||||
ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
else
|
||||
ubuf += sizeof(compat_ulong_t);
|
||||
}
|
||||
|
||||
if (valid_user_regs(&newregs.user_regs))
|
||||
@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target,
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,11 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
|
||||
|
||||
void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
/*
|
||||
* Unmask asynchronous aborts early to catch possible system errors.
|
||||
*/
|
||||
local_async_enable();
|
||||
|
||||
setup_processor();
|
||||
|
||||
setup_machine_fdt(__fdt_pointer);
|
||||
|
@ -160,6 +160,7 @@ asmlinkage void secondary_start_kernel(void)
|
||||
|
||||
local_irq_enable();
|
||||
local_fiq_enable();
|
||||
local_async_enable();
|
||||
|
||||
/*
|
||||
* OK, it's off to the idle thread for us
|
||||
|
@ -50,7 +50,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
CONFIG_BLK_DEV_NS87415=y
|
||||
CONFIG_BLK_DEV_SIIMAGE=m
|
||||
CONFIG_PATA_SIL680=m
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=y
|
||||
|
@ -20,7 +20,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_PA8X00=y
|
||||
CONFIG_MLONGCALLS=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_PREEMPT=y
|
||||
@ -81,8 +80,6 @@ CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
CONFIG_BLK_DEV_PLATFORM=y
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
CONFIG_BLK_DEV_SIIMAGE=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=m
|
||||
CONFIG_BLK_DEV_SR=m
|
||||
@ -94,6 +91,8 @@ CONFIG_SCSI_FC_ATTRS=y
|
||||
CONFIG_SCSI_SAS_LIBSAS=m
|
||||
CONFIG_ISCSI_TCP=m
|
||||
CONFIG_ISCSI_BOOT_SYSFS=m
|
||||
CONFIG_ATA=y
|
||||
CONFIG_PATA_SIL680=y
|
||||
CONFIG_FUSION=y
|
||||
CONFIG_FUSION_SPI=y
|
||||
CONFIG_FUSION_SAS=y
|
||||
@ -114,9 +113,8 @@ CONFIG_INPUT_FF_MEMLESS=m
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
# CONFIG_KEYBOARD_HIL_OLD is not set
|
||||
# CONFIG_KEYBOARD_HIL is not set
|
||||
CONFIG_MOUSE_PS2=m
|
||||
# CONFIG_MOUSE_PS2 is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_CM109=m
|
||||
CONFIG_SERIO_SERPORT=m
|
||||
CONFIG_SERIO_PARKBD=m
|
||||
CONFIG_SERIO_GSCPS2=m
|
||||
@ -167,34 +165,6 @@ CONFIG_SND_VERBOSE_PRINTK=y
|
||||
CONFIG_SND_AD1889=m
|
||||
# CONFIG_SND_USB is not set
|
||||
# CONFIG_SND_GSC is not set
|
||||
CONFIG_HID_A4TECH=m
|
||||
CONFIG_HID_APPLE=m
|
||||
CONFIG_HID_BELKIN=m
|
||||
CONFIG_HID_CHERRY=m
|
||||
CONFIG_HID_CHICONY=m
|
||||
CONFIG_HID_CYPRESS=m
|
||||
CONFIG_HID_DRAGONRISE=m
|
||||
CONFIG_HID_EZKEY=m
|
||||
CONFIG_HID_KYE=m
|
||||
CONFIG_HID_GYRATION=m
|
||||
CONFIG_HID_TWINHAN=m
|
||||
CONFIG_HID_KENSINGTON=m
|
||||
CONFIG_HID_LOGITECH=m
|
||||
CONFIG_HID_LOGITECH_DJ=m
|
||||
CONFIG_HID_MICROSOFT=m
|
||||
CONFIG_HID_MONTEREY=m
|
||||
CONFIG_HID_NTRIG=m
|
||||
CONFIG_HID_ORTEK=m
|
||||
CONFIG_HID_PANTHERLORD=m
|
||||
CONFIG_HID_PETALYNX=m
|
||||
CONFIG_HID_SAMSUNG=m
|
||||
CONFIG_HID_SUNPLUS=m
|
||||
CONFIG_HID_GREENASIA=m
|
||||
CONFIG_HID_SMARTJOYPLUS=m
|
||||
CONFIG_HID_TOPSEED=m
|
||||
CONFIG_HID_THRUSTMASTER=m
|
||||
CONFIG_HID_ZEROPLUS=m
|
||||
CONFIG_USB_HID=m
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
|
@ -24,7 +24,6 @@ CONFIG_MODVERSIONS=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
CONFIG_PA8X00=y
|
||||
CONFIG_MLONGCALLS=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_COMPACTION is not set
|
||||
@ -68,7 +67,6 @@ CONFIG_IDE_GD=m
|
||||
CONFIG_IDE_GD_ATAPI=y
|
||||
CONFIG_BLK_DEV_IDECD=m
|
||||
CONFIG_BLK_DEV_NS87415=y
|
||||
CONFIG_BLK_DEV_SIIMAGE=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
@ -82,6 +80,7 @@ CONFIG_SCSI_ZALON=y
|
||||
CONFIG_SCSI_QLA_ISCSI=m
|
||||
CONFIG_SCSI_DH=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_PATA_SIL680=y
|
||||
CONFIG_ATA_GENERIC=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_MD_LINEAR=m
|
||||
@ -162,7 +161,7 @@ CONFIG_SLIP_MODE_SLIP6=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_KEYBOARD_HIL_OLD is not set
|
||||
# CONFIG_KEYBOARD_HIL is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_MOUSE_PS2 is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_SERIO_SERPORT=m
|
||||
# CONFIG_HP_SDC is not set
|
||||
@ -216,32 +215,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
CONFIG_HID=m
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_HID_DRAGONRISE=m
|
||||
CONFIG_DRAGONRISE_FF=y
|
||||
CONFIG_HID_KYE=m
|
||||
CONFIG_HID_GYRATION=m
|
||||
CONFIG_HID_TWINHAN=m
|
||||
CONFIG_LOGITECH_FF=y
|
||||
CONFIG_LOGIRUMBLEPAD2_FF=y
|
||||
CONFIG_HID_NTRIG=m
|
||||
CONFIG_HID_PANTHERLORD=m
|
||||
CONFIG_PANTHERLORD_FF=y
|
||||
CONFIG_HID_PETALYNX=m
|
||||
CONFIG_HID_SAMSUNG=m
|
||||
CONFIG_HID_SONY=m
|
||||
CONFIG_HID_SUNPLUS=m
|
||||
CONFIG_HID_GREENASIA=m
|
||||
CONFIG_GREENASIA_FF=y
|
||||
CONFIG_HID_SMARTJOYPLUS=m
|
||||
CONFIG_SMARTJOYPLUS_FF=y
|
||||
CONFIG_HID_TOPSEED=m
|
||||
CONFIG_HID_THRUSTMASTER=m
|
||||
CONFIG_THRUSTMASTER_FF=y
|
||||
CONFIG_HID_ZEROPLUS=m
|
||||
CONFIG_ZEROPLUS_FF=y
|
||||
CONFIG_USB_HID=m
|
||||
CONFIG_HID_PID=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB=y
|
||||
@ -251,13 +225,8 @@ CONFIG_USB_DYNAMIC_MINORS=y
|
||||
CONFIG_USB_MON=m
|
||||
CONFIG_USB_WUSB_CBAF=m
|
||||
CONFIG_USB_XHCI_HCD=m
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
CONFIG_USB_OHCI_HCD=m
|
||||
CONFIG_USB_R8A66597_HCD=m
|
||||
CONFIG_USB_ACM=m
|
||||
CONFIG_USB_PRINTER=m
|
||||
CONFIG_USB_WDM=m
|
||||
CONFIG_USB_TMC=m
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
|
@ -6,5 +6,3 @@
|
||||
* This is used for 16550-compatible UARTs
|
||||
*/
|
||||
#define BASE_BAUD ( 1843200 / 16 )
|
||||
|
||||
#define SERIAL_PORT_DFNS
|
||||
|
@ -36,6 +36,9 @@
|
||||
* HP PARISC Hardware Database
|
||||
* Access to this database is only possible during bootup
|
||||
* so don't reference this table after starting the init process
|
||||
*
|
||||
* NOTE: Product names which are listed here and ends with a '?'
|
||||
* are guessed. If you know the correct name, please let us know.
|
||||
*/
|
||||
|
||||
static struct hp_hardware hp_hardware_list[] = {
|
||||
@ -222,7 +225,7 @@ static struct hp_hardware hp_hardware_list[] = {
|
||||
{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
|
||||
{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
|
||||
{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
|
||||
{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
|
||||
{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+ (rp5470)?"},
|
||||
{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
|
||||
{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
|
||||
{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
|
||||
@ -276,9 +279,11 @@ static struct hp_hardware hp_hardware_list[] = {
|
||||
{HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
|
||||
{HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
|
||||
{HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"},
|
||||
{HPHW_NPROC,0x88B,0x4,0x91,"Crestone Peak Fast?"},
|
||||
{HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"},
|
||||
{HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"},
|
||||
{HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"},
|
||||
{HPHW_NPROC,0x892,0x4,0x91,"Mt. Hamilton Slow Mako+?"},
|
||||
{HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"},
|
||||
{HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"},
|
||||
{HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"},
|
||||
|
@ -41,9 +41,7 @@ END(boot_args)
|
||||
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */
|
||||
.import $global$ /* forward declaration */
|
||||
#endif /*!CONFIG_64BIT*/
|
||||
.export _stext,data /* Kernel want it this way! */
|
||||
_stext:
|
||||
ENTRY(stext)
|
||||
ENTRY(parisc_kernel_start)
|
||||
.proc
|
||||
.callinfo
|
||||
|
||||
@ -347,7 +345,7 @@ smp_slave_stext:
|
||||
.procend
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
ENDPROC(stext)
|
||||
ENDPROC(parisc_kernel_start)
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
.section .data..read_mostly
|
||||
|
@ -61,8 +61,15 @@ static int get_offset(struct address_space *mapping)
|
||||
return (unsigned long) mapping >> 8;
|
||||
}
|
||||
|
||||
static unsigned long get_shared_area(struct address_space *mapping,
|
||||
unsigned long addr, unsigned long len, unsigned long pgoff)
|
||||
static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff)
|
||||
{
|
||||
struct address_space *mapping = filp ? filp->f_mapping : NULL;
|
||||
|
||||
return (get_offset(mapping) + pgoff) << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static unsigned long get_shared_area(struct file *filp, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff)
|
||||
{
|
||||
struct vm_unmapped_area_info info;
|
||||
|
||||
@ -71,7 +78,7 @@ static unsigned long get_shared_area(struct address_space *mapping,
|
||||
info.low_limit = PAGE_ALIGN(addr);
|
||||
info.high_limit = TASK_SIZE;
|
||||
info.align_mask = PAGE_MASK & (SHMLBA - 1);
|
||||
info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
|
||||
info.align_offset = shared_align_offset(filp, pgoff);
|
||||
return vm_unmapped_area(&info);
|
||||
}
|
||||
|
||||
@ -82,20 +89,18 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
return -ENOMEM;
|
||||
if (flags & MAP_FIXED) {
|
||||
if ((flags & MAP_SHARED) &&
|
||||
(addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
|
||||
(addr - shared_align_offset(filp, pgoff)) & (SHMLBA - 1))
|
||||
return -EINVAL;
|
||||
return addr;
|
||||
}
|
||||
if (!addr)
|
||||
addr = TASK_UNMAPPED_BASE;
|
||||
|
||||
if (filp) {
|
||||
addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
|
||||
} else if(flags & MAP_SHARED) {
|
||||
addr = get_shared_area(NULL, addr, len, pgoff);
|
||||
} else {
|
||||
if (filp || (flags & MAP_SHARED))
|
||||
addr = get_shared_area(filp, addr, len, pgoff);
|
||||
else
|
||||
addr = get_unshared_area(addr, len);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ void unwind_table_remove(struct unwind_table *table)
|
||||
}
|
||||
|
||||
/* Called from setup_arch to import the kernel unwind info */
|
||||
int unwind_init(void)
|
||||
int __init unwind_init(void)
|
||||
{
|
||||
long start, stop;
|
||||
register unsigned long gp __asm__ ("r27");
|
||||
@ -233,7 +233,6 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
|
||||
e = find_unwind_entry(info->ip);
|
||||
if (e == NULL) {
|
||||
unsigned long sp;
|
||||
extern char _stext[], _etext[];
|
||||
|
||||
dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip);
|
||||
|
||||
@ -281,8 +280,7 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
|
||||
break;
|
||||
info->prev_ip = tmp;
|
||||
sp = info->prev_sp;
|
||||
} while (info->prev_ip < (unsigned long)_stext ||
|
||||
info->prev_ip > (unsigned long)_etext);
|
||||
} while (!kernel_text_address(info->prev_ip));
|
||||
|
||||
info->rp = 0;
|
||||
|
||||
@ -435,9 +433,8 @@ unsigned long return_address(unsigned int level)
|
||||
do {
|
||||
if (unwind_once(&info) < 0 || info.ip == 0)
|
||||
return 0;
|
||||
if (!__kernel_text_address(info.ip)) {
|
||||
if (!kernel_text_address(info.ip))
|
||||
return 0;
|
||||
}
|
||||
} while (info.ip && level--);
|
||||
|
||||
return info.ip;
|
||||
|
@ -6,24 +6,19 @@
|
||||
* Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
|
||||
* Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
|
||||
* Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org>
|
||||
* Copyright (C) 2006 Helge Deller <deller@gmx.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Copyright (C) 2006-2013 Helge Deller <deller@gmx.de>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Put page table entries (swapper_pg_dir) as the first thing in .bss. This
|
||||
* will ensure that it has .bss alignment (PAGE_SIZE).
|
||||
*/
|
||||
#define BSS_FIRST_SECTIONS *(.data..vm0.pmd) \
|
||||
*(.data..vm0.pgd) \
|
||||
*(.data..vm0.pte)
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
/* needed for the processor specific cache alignment size */
|
||||
#include <asm/cache.h>
|
||||
#include <asm/page.h>
|
||||
@ -39,7 +34,7 @@ OUTPUT_FORMAT("elf64-hppa-linux")
|
||||
OUTPUT_ARCH(hppa:hppa2.0w)
|
||||
#endif
|
||||
|
||||
ENTRY(_stext)
|
||||
ENTRY(parisc_kernel_start)
|
||||
#ifndef CONFIG_64BIT
|
||||
jiffies = jiffies_64 + 4;
|
||||
#else
|
||||
@ -49,11 +44,29 @@ SECTIONS
|
||||
{
|
||||
. = KERNEL_BINARY_TEXT_START;
|
||||
|
||||
__init_begin = .;
|
||||
HEAD_TEXT_SECTION
|
||||
INIT_TEXT_SECTION(8)
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
INIT_DATA_SECTION(PAGE_SIZE)
|
||||
/* we have to discard exit text and such at runtime, not link time */
|
||||
.exit.text :
|
||||
{
|
||||
EXIT_TEXT
|
||||
}
|
||||
.exit.data :
|
||||
{
|
||||
EXIT_DATA
|
||||
}
|
||||
PERCPU_SECTION(8)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
/* freed after init ends here */
|
||||
|
||||
_text = .; /* Text and read-only data */
|
||||
.head ALIGN(16) : {
|
||||
HEAD_TEXT
|
||||
} = 0
|
||||
.text ALIGN(16) : {
|
||||
_stext = .;
|
||||
.text ALIGN(PAGE_SIZE) : {
|
||||
TEXT_TEXT
|
||||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
@ -68,13 +81,35 @@ SECTIONS
|
||||
*(.lock.text) /* out-of-line lock text */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
/* End of text section */
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
_etext = .;
|
||||
/* End of text section */
|
||||
|
||||
/* Start of data section */
|
||||
_sdata = .;
|
||||
|
||||
RODATA
|
||||
RO_DATA_SECTION(8)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
. = ALIGN(16);
|
||||
/* Linkage tables */
|
||||
.opd : {
|
||||
*(.opd)
|
||||
} PROVIDE (__gp = .);
|
||||
.plt : {
|
||||
*(.plt)
|
||||
}
|
||||
.dlt : {
|
||||
*(.dlt)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* unwind info */
|
||||
.PARISC.unwind : {
|
||||
__start___unwind = .;
|
||||
*(.PARISC.unwind)
|
||||
__stop___unwind = .;
|
||||
}
|
||||
|
||||
/* writeable */
|
||||
/* Make sure this is page aligned so
|
||||
@ -84,14 +119,7 @@ SECTIONS
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
data_start = .;
|
||||
|
||||
/* unwind info */
|
||||
.PARISC.unwind : {
|
||||
__start___unwind = .;
|
||||
*(.PARISC.unwind)
|
||||
__stop___unwind = .;
|
||||
}
|
||||
|
||||
EXCEPTION_TABLE(16)
|
||||
EXCEPTION_TABLE(8)
|
||||
NOTES
|
||||
|
||||
/* Data */
|
||||
@ -107,54 +135,8 @@ SECTIONS
|
||||
_edata = .;
|
||||
|
||||
/* BSS */
|
||||
__bss_start = .;
|
||||
/* page table entries need to be PAGE_SIZE aligned */
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
.data..vmpages : {
|
||||
*(.data..vm0.pmd)
|
||||
*(.data..vm0.pgd)
|
||||
*(.data..vm0.pte)
|
||||
}
|
||||
.bss : {
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
__bss_stop = .;
|
||||
BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 8)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
. = ALIGN(16);
|
||||
/* Linkage tables */
|
||||
.opd : {
|
||||
*(.opd)
|
||||
} PROVIDE (__gp = .);
|
||||
.plt : {
|
||||
*(.plt)
|
||||
}
|
||||
.dlt : {
|
||||
*(.dlt)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* reserve space for interrupt stack by aligning __init* to 16k */
|
||||
. = ALIGN(16384);
|
||||
__init_begin = .;
|
||||
INIT_TEXT_SECTION(16384)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
INIT_DATA_SECTION(16)
|
||||
/* we have to discard exit text and such at runtime, not link time */
|
||||
.exit.text :
|
||||
{
|
||||
EXIT_TEXT
|
||||
}
|
||||
.exit.data :
|
||||
{
|
||||
EXIT_DATA
|
||||
}
|
||||
|
||||
PERCPU_SECTION(L1_CACHE_BYTES)
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
/* freed after init ends here */
|
||||
_end = . ;
|
||||
|
||||
STABS_DEBUG
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <asm/sections.h>
|
||||
|
||||
extern int data_start;
|
||||
extern void parisc_kernel_start(void); /* Kernel entry point in head.S */
|
||||
|
||||
#if PT_NLEVELS == 3
|
||||
/* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout
|
||||
@ -324,8 +325,9 @@ static void __init setup_bootmem(void)
|
||||
reserve_bootmem_node(NODE_DATA(0), 0UL,
|
||||
(unsigned long)(PAGE0->mem_free +
|
||||
PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT);
|
||||
reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
|
||||
(unsigned long)(_end - _text), BOOTMEM_DEFAULT);
|
||||
reserve_bootmem_node(NODE_DATA(0), __pa(KERNEL_BINARY_TEXT_START),
|
||||
(unsigned long)(_end - KERNEL_BINARY_TEXT_START),
|
||||
BOOTMEM_DEFAULT);
|
||||
reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
|
||||
((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
|
||||
BOOTMEM_DEFAULT);
|
||||
@ -378,6 +380,17 @@ static void __init setup_bootmem(void)
|
||||
request_resource(&sysram_resources[0], &pdcdata_resource);
|
||||
}
|
||||
|
||||
static int __init parisc_text_address(unsigned long vaddr)
|
||||
{
|
||||
static unsigned long head_ptr __initdata;
|
||||
|
||||
if (!head_ptr)
|
||||
head_ptr = PAGE_MASK & (unsigned long)
|
||||
dereference_function_descriptor(&parisc_kernel_start);
|
||||
|
||||
return core_kernel_text(vaddr) || vaddr == head_ptr;
|
||||
}
|
||||
|
||||
static void __init map_pages(unsigned long start_vaddr,
|
||||
unsigned long start_paddr, unsigned long size,
|
||||
pgprot_t pgprot, int force)
|
||||
@ -466,7 +479,7 @@ static void __init map_pages(unsigned long start_vaddr,
|
||||
*/
|
||||
if (force)
|
||||
pte = __mk_pte(address, pgprot);
|
||||
else if (core_kernel_text(vaddr) &&
|
||||
else if (parisc_text_address(vaddr) &&
|
||||
address != fv_addr)
|
||||
pte = __mk_pte(address, PAGE_KERNEL_EXEC);
|
||||
else
|
||||
|
@ -75,8 +75,10 @@ LDEMULATION := lppc
|
||||
GNUTARGET := powerpcle
|
||||
MULTIPLEWORD := -mno-multiple
|
||||
else
|
||||
ifeq ($(call cc-option-yn,-mbig-endian),y)
|
||||
override CC += -mbig-endian
|
||||
override AS += -mbig-endian
|
||||
endif
|
||||
override LD += -EB
|
||||
LDEMULATION := ppc
|
||||
GNUTARGET := powerpc
|
||||
@ -128,7 +130,12 @@ CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5)
|
||||
CFLAGS-$(CONFIG_POWER6_CPU) += $(call cc-option,-mcpu=power6)
|
||||
CFLAGS-$(CONFIG_POWER7_CPU) += $(call cc-option,-mcpu=power7)
|
||||
|
||||
# Altivec option not allowed with e500mc64 in GCC.
|
||||
ifeq ($(CONFIG_ALTIVEC),y)
|
||||
E5500_CPU := -mcpu=powerpc64
|
||||
else
|
||||
E5500_CPU := $(call cc-option,-mcpu=e500mc64,-mcpu=powerpc64)
|
||||
endif
|
||||
CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU)
|
||||
CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU))
|
||||
|
||||
|
@ -637,14 +637,14 @@
|
||||
tlu@2f000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x2f000 0x1000>;
|
||||
interupts = <61 2 >;
|
||||
interrupts = <61 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
|
||||
tlu@15000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x15000 0x1000>;
|
||||
interupts = <75 2>;
|
||||
interrupts = <75 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
};
|
||||
|
@ -547,14 +547,14 @@
|
||||
tlu@2f000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x2f000 0x1000>;
|
||||
interupts = <61 2 >;
|
||||
interrupts = <61 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
|
||||
tlu@15000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x15000 0x1000>;
|
||||
interupts = <75 2>;
|
||||
interrupts = <75 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
};
|
||||
|
@ -583,14 +583,14 @@
|
||||
tlu@2f000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x2f000 0x1000>;
|
||||
interupts = <61 2 >;
|
||||
interrupts = <61 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
|
||||
tlu@15000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x15000 0x1000>;
|
||||
interupts = <75 2>;
|
||||
interrupts = <75 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
};
|
||||
|
@ -545,14 +545,14 @@
|
||||
tlu@2f000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x2f000 0x1000>;
|
||||
interupts = <61 2 >;
|
||||
interrupts = <61 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
|
||||
tlu@15000 {
|
||||
compatible = "fsl,mpc8572-tlu", "fsl_tlu";
|
||||
reg = <0x15000 0x1000>;
|
||||
interupts = <75 2>;
|
||||
interrupts = <75 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
};
|
||||
|
@ -71,18 +71,32 @@ udelay:
|
||||
add r4,r4,r5
|
||||
addi r4,r4,-1
|
||||
divw r4,r4,r5 /* BUS ticks */
|
||||
#ifdef CONFIG_8xx
|
||||
1: mftbu r5
|
||||
mftb r6
|
||||
mftbu r7
|
||||
#else
|
||||
1: mfspr r5, SPRN_TBRU
|
||||
mfspr r6, SPRN_TBRL
|
||||
mfspr r7, SPRN_TBRU
|
||||
#endif
|
||||
cmpw 0,r5,r7
|
||||
bne 1b /* Get [synced] base time */
|
||||
addc r9,r6,r4 /* Compute end time */
|
||||
addze r8,r5
|
||||
#ifdef CONFIG_8xx
|
||||
2: mftbu r5
|
||||
#else
|
||||
2: mfspr r5, SPRN_TBRU
|
||||
#endif
|
||||
cmpw 0,r5,r8
|
||||
blt 2b
|
||||
bgt 3f
|
||||
#ifdef CONFIG_8xx
|
||||
mftb r6
|
||||
#else
|
||||
mfspr r6, SPRN_TBRL
|
||||
#endif
|
||||
cmpw 0,r6,r9
|
||||
blt 2b
|
||||
3: blr
|
||||
|
@ -16,6 +16,7 @@ struct vmemmap_backing {
|
||||
unsigned long phys;
|
||||
unsigned long virt_addr;
|
||||
};
|
||||
extern struct vmemmap_backing *vmemmap_list;
|
||||
|
||||
/*
|
||||
* Functions that deal with pagetables that could be at any level of
|
||||
|
@ -366,6 +366,8 @@ BEGIN_FTR_SECTION_NESTED(96); \
|
||||
cmpwi dest,0; \
|
||||
beq- 90b; \
|
||||
END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
|
||||
#elif defined(CONFIG_8xx)
|
||||
#define MFTB(dest) mftb dest
|
||||
#else
|
||||
#define MFTB(dest) mfspr dest, SPRN_TBRL
|
||||
#endif
|
||||
|
@ -1174,12 +1174,19 @@
|
||||
|
||||
#else /* __powerpc64__ */
|
||||
|
||||
#if defined(CONFIG_8xx)
|
||||
#define mftbl() ({unsigned long rval; \
|
||||
asm volatile("mftbl %0" : "=r" (rval)); rval;})
|
||||
#define mftbu() ({unsigned long rval; \
|
||||
asm volatile("mftbu %0" : "=r" (rval)); rval;})
|
||||
#else
|
||||
#define mftbl() ({unsigned long rval; \
|
||||
asm volatile("mfspr %0, %1" : "=r" (rval) : \
|
||||
"i" (SPRN_TBRL)); rval;})
|
||||
#define mftbu() ({unsigned long rval; \
|
||||
asm volatile("mfspr %0, %1" : "=r" (rval) : \
|
||||
"i" (SPRN_TBRU)); rval;})
|
||||
#endif
|
||||
#endif /* !__powerpc64__ */
|
||||
|
||||
#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
|
||||
|
@ -29,7 +29,11 @@ static inline cycles_t get_cycles(void)
|
||||
ret = 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
#ifdef CONFIG_8xx
|
||||
"97: mftb %0\n"
|
||||
#else
|
||||
"97: mfspr %0, %2\n"
|
||||
#endif
|
||||
"99:\n"
|
||||
".section __ftr_fixup,\"a\"\n"
|
||||
".align 2\n"
|
||||
@ -41,7 +45,11 @@ static inline cycles_t get_cycles(void)
|
||||
" .long 0\n"
|
||||
" .long 0\n"
|
||||
".previous"
|
||||
#ifdef CONFIG_8xx
|
||||
: "=r" (ret) : "i" (CPU_FTR_601));
|
||||
#else
|
||||
: "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
|
||||
#endif
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
@ -75,6 +76,17 @@ void arch_crash_save_vmcoreinfo(void)
|
||||
#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||||
VMCOREINFO_SYMBOL(contig_page_data);
|
||||
#endif
|
||||
#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
|
||||
VMCOREINFO_SYMBOL(vmemmap_list);
|
||||
VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
|
||||
VMCOREINFO_SYMBOL(mmu_psize_defs);
|
||||
VMCOREINFO_STRUCT_SIZE(vmemmap_backing);
|
||||
VMCOREINFO_OFFSET(vmemmap_backing, list);
|
||||
VMCOREINFO_OFFSET(vmemmap_backing, phys);
|
||||
VMCOREINFO_OFFSET(vmemmap_backing, virt_addr);
|
||||
VMCOREINFO_STRUCT_SIZE(mmu_psize_def);
|
||||
VMCOREINFO_OFFSET(mmu_psize_def, shift);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -210,7 +210,7 @@ static void __init nvram_print_partitions(char * label)
|
||||
printk(KERN_WARNING "--------%s---------\n", label);
|
||||
printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
|
||||
list_for_each_entry(tmp_part, &nvram_partitions, partition) {
|
||||
printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n",
|
||||
printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12.12s\n",
|
||||
tmp_part->index, tmp_part->header.signature,
|
||||
tmp_part->header.checksum, tmp_part->header.length,
|
||||
tmp_part->header.name);
|
||||
|
@ -445,6 +445,12 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
if (copy_fpr_to_user(&frame->mc_fregs, current))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Clear the MSR VSX bit to indicate there is no valid state attached
|
||||
* to this context, except in the specific case below where we set it.
|
||||
*/
|
||||
msr &= ~MSR_VSX;
|
||||
#ifdef CONFIG_VSX
|
||||
/*
|
||||
* Copy VSR 0-31 upper half from thread_struct to local
|
||||
@ -457,15 +463,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
|
||||
if (copy_vsx_to_user(&frame->mc_vsregs, current))
|
||||
return 1;
|
||||
msr |= MSR_VSX;
|
||||
} else if (!ctx_has_vsx_region)
|
||||
/*
|
||||
* With a small context structure we can't hold the VSX
|
||||
* registers, hence clear the MSR value to indicate the state
|
||||
* was not saved.
|
||||
*/
|
||||
msr &= ~MSR_VSX;
|
||||
|
||||
|
||||
}
|
||||
#endif /* CONFIG_VSX */
|
||||
#ifdef CONFIG_SPE
|
||||
/* save spe registers */
|
||||
|
@ -122,6 +122,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
|
||||
flush_fp_to_thread(current);
|
||||
/* copy fpr regs and fpscr */
|
||||
err |= copy_fpr_to_user(&sc->fp_regs, current);
|
||||
|
||||
/*
|
||||
* Clear the MSR VSX bit to indicate there is no valid state attached
|
||||
* to this context, except in the specific case below where we set it.
|
||||
*/
|
||||
msr &= ~MSR_VSX;
|
||||
#ifdef CONFIG_VSX
|
||||
/*
|
||||
* Copy VSX low doubleword to local buffer for formatting,
|
||||
|
@ -232,9 +232,15 @@ __do_get_tspec:
|
||||
lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
|
||||
|
||||
/* Get a stable TB value */
|
||||
#ifdef CONFIG_8xx
|
||||
2: mftbu r3
|
||||
mftbl r4
|
||||
mftbu r0
|
||||
#else
|
||||
2: mfspr r3, SPRN_TBRU
|
||||
mfspr r4, SPRN_TBRL
|
||||
mfspr r0, SPRN_TBRU
|
||||
#endif
|
||||
cmplw cr0,r3,r0
|
||||
bne- 2b
|
||||
|
||||
|
@ -117,6 +117,5 @@ void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
|
||||
struct hstate *hstate = hstate_file(vma->vm_file);
|
||||
unsigned long tsize = huge_page_shift(hstate) - 10;
|
||||
|
||||
__flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, tsize, 0);
|
||||
|
||||
__flush_tlb_page(vma->vm_mm, vmaddr, tsize, 0);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
|
||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
|
||||
{
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
if (is_vm_hugetlb_page(vma))
|
||||
if (vma && is_vm_hugetlb_page(vma))
|
||||
flush_hugetlb_page(vma, vmaddr);
|
||||
#endif
|
||||
|
||||
|
@ -404,13 +404,27 @@ config PPC_DOORBELL
|
||||
|
||||
endmenu
|
||||
|
||||
config CPU_LITTLE_ENDIAN
|
||||
bool "Build little endian kernel"
|
||||
default n
|
||||
choice
|
||||
prompt "Endianness selection"
|
||||
default CPU_BIG_ENDIAN
|
||||
help
|
||||
This option selects whether a big endian or little endian kernel will
|
||||
be built.
|
||||
|
||||
config CPU_BIG_ENDIAN
|
||||
bool "Build big endian kernel"
|
||||
help
|
||||
Build a big endian kernel.
|
||||
|
||||
If unsure, select this option.
|
||||
|
||||
config CPU_LITTLE_ENDIAN
|
||||
bool "Build little endian kernel"
|
||||
help
|
||||
Build a little endian kernel.
|
||||
|
||||
Note that if cross compiling a little endian kernel,
|
||||
CROSS_COMPILE must point to a toolchain capable of targeting
|
||||
little endian powerpc.
|
||||
|
||||
endchoice
|
||||
|
@ -101,7 +101,7 @@ config S390
|
||||
select GENERIC_CPU_DEVICES if !SMP
|
||||
select GENERIC_FIND_FIRST_BIT
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_TIME_VSYSCALL_OLD
|
||||
select GENERIC_TIME_VSYSCALL
|
||||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
|
@ -35,7 +35,6 @@ static u8 *ctrblk;
|
||||
static char keylen_flag;
|
||||
|
||||
struct s390_aes_ctx {
|
||||
u8 iv[AES_BLOCK_SIZE];
|
||||
u8 key[AES_MAX_KEY_SIZE];
|
||||
long enc;
|
||||
long dec;
|
||||
@ -56,8 +55,7 @@ struct pcc_param {
|
||||
|
||||
struct s390_xts_ctx {
|
||||
u8 key[32];
|
||||
u8 xts_param[16];
|
||||
struct pcc_param pcc;
|
||||
u8 pcc_key[32];
|
||||
long enc;
|
||||
long dec;
|
||||
int key_len;
|
||||
@ -441,30 +439,36 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
return aes_set_key(tfm, in_key, key_len);
|
||||
}
|
||||
|
||||
static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
|
||||
static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
int ret = blkcipher_walk_virt(desc, walk);
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
struct {
|
||||
u8 iv[AES_BLOCK_SIZE];
|
||||
u8 key[AES_MAX_KEY_SIZE];
|
||||
} param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
memcpy(param, walk->iv, AES_BLOCK_SIZE);
|
||||
memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
|
||||
memcpy(param.key, sctx->key, sctx->key_len);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
u8 *out = walk->dst.virt.addr;
|
||||
u8 *in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_kmc(func, param, out, in, n);
|
||||
ret = crypt_s390_kmc(func, ¶m, out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
nbytes &= AES_BLOCK_SIZE - 1;
|
||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||
} while ((nbytes = walk->nbytes));
|
||||
memcpy(walk->iv, param, AES_BLOCK_SIZE);
|
||||
memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
@ -481,7 +485,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
|
||||
return fallback_blk_enc(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
|
||||
return cbc_aes_crypt(desc, sctx->enc, &walk);
|
||||
}
|
||||
|
||||
static int cbc_aes_decrypt(struct blkcipher_desc *desc,
|
||||
@ -495,7 +499,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
|
||||
return fallback_blk_dec(desc, dst, src, nbytes);
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
|
||||
return cbc_aes_crypt(desc, sctx->dec, &walk);
|
||||
}
|
||||
|
||||
static struct crypto_alg cbc_aes_alg = {
|
||||
@ -586,7 +590,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
xts_ctx->enc = KM_XTS_128_ENCRYPT;
|
||||
xts_ctx->dec = KM_XTS_128_DECRYPT;
|
||||
memcpy(xts_ctx->key + 16, in_key, 16);
|
||||
memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16);
|
||||
memcpy(xts_ctx->pcc_key + 16, in_key + 16, 16);
|
||||
break;
|
||||
case 48:
|
||||
xts_ctx->enc = 0;
|
||||
@ -597,7 +601,7 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||
xts_ctx->enc = KM_XTS_256_ENCRYPT;
|
||||
xts_ctx->dec = KM_XTS_256_DECRYPT;
|
||||
memcpy(xts_ctx->key, in_key, 32);
|
||||
memcpy(xts_ctx->pcc.key, in_key + 32, 32);
|
||||
memcpy(xts_ctx->pcc_key, in_key + 32, 32);
|
||||
break;
|
||||
default:
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
@ -616,29 +620,33 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
unsigned int n;
|
||||
u8 *in, *out;
|
||||
void *param;
|
||||
struct pcc_param pcc_param;
|
||||
struct {
|
||||
u8 key[32];
|
||||
u8 init[16];
|
||||
} xts_param;
|
||||
|
||||
if (!nbytes)
|
||||
goto out;
|
||||
|
||||
memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block));
|
||||
memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit));
|
||||
memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts));
|
||||
memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak));
|
||||
param = xts_ctx->pcc.key + offset;
|
||||
ret = crypt_s390_pcc(func, param);
|
||||
memset(pcc_param.block, 0, sizeof(pcc_param.block));
|
||||
memset(pcc_param.bit, 0, sizeof(pcc_param.bit));
|
||||
memset(pcc_param.xts, 0, sizeof(pcc_param.xts));
|
||||
memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
|
||||
memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
|
||||
ret = crypt_s390_pcc(func, &pcc_param.key[offset]);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
|
||||
memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16);
|
||||
param = xts_ctx->key + offset;
|
||||
memcpy(xts_param.key, xts_ctx->key, 32);
|
||||
memcpy(xts_param.init, pcc_param.xts, 16);
|
||||
do {
|
||||
/* only use complete blocks */
|
||||
n = nbytes & ~(AES_BLOCK_SIZE - 1);
|
||||
out = walk->dst.virt.addr;
|
||||
in = walk->src.virt.addr;
|
||||
|
||||
ret = crypt_s390_km(func, param, out, in, n);
|
||||
ret = crypt_s390_km(func, &xts_param.key[offset], out, in, n);
|
||||
if (ret < 0 || ret != n)
|
||||
return -EIO;
|
||||
|
||||
|
@ -48,33 +48,21 @@ static inline void clear_page(void *page)
|
||||
: "memory", "cc");
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_page uses the mvcl instruction with 0xb0 padding byte in order to
|
||||
* bypass caches when copying a page. Especially when copying huge pages
|
||||
* this keeps L1 and L2 data caches alive.
|
||||
*/
|
||||
static inline void copy_page(void *to, void *from)
|
||||
{
|
||||
if (MACHINE_HAS_MVPG) {
|
||||
register unsigned long reg0 asm ("0") = 0;
|
||||
asm volatile(
|
||||
" mvpg %0,%1"
|
||||
: : "a" (to), "a" (from), "d" (reg0)
|
||||
: "memory", "cc");
|
||||
} else
|
||||
asm volatile(
|
||||
" mvc 0(256,%0),0(%1)\n"
|
||||
" mvc 256(256,%0),256(%1)\n"
|
||||
" mvc 512(256,%0),512(%1)\n"
|
||||
" mvc 768(256,%0),768(%1)\n"
|
||||
" mvc 1024(256,%0),1024(%1)\n"
|
||||
" mvc 1280(256,%0),1280(%1)\n"
|
||||
" mvc 1536(256,%0),1536(%1)\n"
|
||||
" mvc 1792(256,%0),1792(%1)\n"
|
||||
" mvc 2048(256,%0),2048(%1)\n"
|
||||
" mvc 2304(256,%0),2304(%1)\n"
|
||||
" mvc 2560(256,%0),2560(%1)\n"
|
||||
" mvc 2816(256,%0),2816(%1)\n"
|
||||
" mvc 3072(256,%0),3072(%1)\n"
|
||||
" mvc 3328(256,%0),3328(%1)\n"
|
||||
" mvc 3584(256,%0),3584(%1)\n"
|
||||
" mvc 3840(256,%0),3840(%1)\n"
|
||||
: : "a" (to), "a" (from) : "memory");
|
||||
register void *reg2 asm ("2") = to;
|
||||
register unsigned long reg3 asm ("3") = 0x1000;
|
||||
register void *reg4 asm ("4") = from;
|
||||
register unsigned long reg5 asm ("5") = 0xb0001000;
|
||||
asm volatile(
|
||||
" mvcl 2,4"
|
||||
: "+d" (reg2), "+d" (reg3), "+d" (reg4), "+d" (reg5)
|
||||
: : "memory", "cc");
|
||||
}
|
||||
|
||||
#define clear_user_page(page, vaddr, pg) clear_page(page)
|
||||
|
@ -26,8 +26,9 @@ struct vdso_data {
|
||||
__u64 wtom_clock_nsec; /* 0x28 */
|
||||
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
|
||||
__u32 tz_dsttime; /* Type of dst correction 0x34 */
|
||||
__u32 ectg_available;
|
||||
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
|
||||
__u32 ectg_available; /* ECTG instruction present 0x38 */
|
||||
__u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
|
||||
__u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
|
||||
};
|
||||
|
||||
struct vdso_per_cpu_data {
|
||||
|
@ -65,7 +65,8 @@ int main(void)
|
||||
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
|
||||
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
|
||||
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
|
||||
DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
|
||||
DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
|
||||
DEFINE(__VDSO_TK_SHIFT, offsetof(struct vdso_data, tk_shift));
|
||||
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
|
||||
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
|
||||
/* constants used by the vdso */
|
||||
|
@ -194,7 +194,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
||||
return -EINVAL;
|
||||
|
||||
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
|
||||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
|
||||
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
|
||||
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
|
||||
(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
|
||||
|
@ -78,7 +78,7 @@ PGM_CHECK_DEFAULT /* 34 */
|
||||
PGM_CHECK_DEFAULT /* 35 */
|
||||
PGM_CHECK_DEFAULT /* 36 */
|
||||
PGM_CHECK_DEFAULT /* 37 */
|
||||
PGM_CHECK_DEFAULT /* 38 */
|
||||
PGM_CHECK_64BIT(do_dat_exception) /* 38 */
|
||||
PGM_CHECK_64BIT(do_dat_exception) /* 39 */
|
||||
PGM_CHECK_64BIT(do_dat_exception) /* 3a */
|
||||
PGM_CHECK_64BIT(do_dat_exception) /* 3b */
|
||||
|
@ -94,7 +94,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
|
||||
return -EINVAL;
|
||||
|
||||
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
|
||||
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
|
||||
regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
|
||||
(user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
|
||||
/* Check for invalid user address space control. */
|
||||
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
|
||||
|
@ -108,20 +108,10 @@ static void fixup_clock_comparator(unsigned long long delta)
|
||||
set_clock_comparator(S390_lowcore.clock_comparator);
|
||||
}
|
||||
|
||||
static int s390_next_ktime(ktime_t expires,
|
||||
static int s390_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
struct timespec ts;
|
||||
u64 nsecs;
|
||||
|
||||
ts.tv_sec = ts.tv_nsec = 0;
|
||||
monotonic_to_bootbased(&ts);
|
||||
nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
|
||||
do_div(nsecs, 125);
|
||||
S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
|
||||
/* Program the maximum value if we have an overflow (== year 2042) */
|
||||
if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
|
||||
S390_lowcore.clock_comparator = -1ULL;
|
||||
S390_lowcore.clock_comparator = get_tod_clock() + delta;
|
||||
set_clock_comparator(S390_lowcore.clock_comparator);
|
||||
return 0;
|
||||
}
|
||||
@ -146,15 +136,14 @@ void init_cpu_timer(void)
|
||||
cpu = smp_processor_id();
|
||||
cd = &per_cpu(comparators, cpu);
|
||||
cd->name = "comparator";
|
||||
cd->features = CLOCK_EVT_FEAT_ONESHOT |
|
||||
CLOCK_EVT_FEAT_KTIME;
|
||||
cd->features = CLOCK_EVT_FEAT_ONESHOT;
|
||||
cd->mult = 16777;
|
||||
cd->shift = 12;
|
||||
cd->min_delta_ns = 1;
|
||||
cd->max_delta_ns = LONG_MAX;
|
||||
cd->rating = 400;
|
||||
cd->cpumask = cpumask_of(cpu);
|
||||
cd->set_next_ktime = s390_next_ktime;
|
||||
cd->set_next_event = s390_next_event;
|
||||
cd->set_mode = s390_set_mode;
|
||||
|
||||
clockevents_register_device(cd);
|
||||
@ -221,21 +210,30 @@ struct clocksource * __init clocksource_default_clock(void)
|
||||
return &clocksource_tod;
|
||||
}
|
||||
|
||||
void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm,
|
||||
struct clocksource *clock, u32 mult)
|
||||
void update_vsyscall(struct timekeeper *tk)
|
||||
{
|
||||
if (clock != &clocksource_tod)
|
||||
u64 nsecps;
|
||||
|
||||
if (tk->clock != &clocksource_tod)
|
||||
return;
|
||||
|
||||
/* Make userspace gettimeofday spin until we're done. */
|
||||
++vdso_data->tb_update_count;
|
||||
smp_wmb();
|
||||
vdso_data->xtime_tod_stamp = clock->cycle_last;
|
||||
vdso_data->xtime_clock_sec = wall_time->tv_sec;
|
||||
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
|
||||
vdso_data->wtom_clock_sec = wtm->tv_sec;
|
||||
vdso_data->wtom_clock_nsec = wtm->tv_nsec;
|
||||
vdso_data->ntp_mult = mult;
|
||||
vdso_data->xtime_tod_stamp = tk->clock->cycle_last;
|
||||
vdso_data->xtime_clock_sec = tk->xtime_sec;
|
||||
vdso_data->xtime_clock_nsec = tk->xtime_nsec;
|
||||
vdso_data->wtom_clock_sec =
|
||||
tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
|
||||
vdso_data->wtom_clock_nsec = tk->xtime_nsec +
|
||||
+ (tk->wall_to_monotonic.tv_nsec << tk->shift);
|
||||
nsecps = (u64) NSEC_PER_SEC << tk->shift;
|
||||
while (vdso_data->wtom_clock_nsec >= nsecps) {
|
||||
vdso_data->wtom_clock_nsec -= nsecps;
|
||||
vdso_data->wtom_clock_sec++;
|
||||
}
|
||||
vdso_data->tk_mult = tk->mult;
|
||||
vdso_data->tk_shift = tk->shift;
|
||||
smp_wmb();
|
||||
++vdso_data->tb_update_count;
|
||||
}
|
||||
|
@ -38,25 +38,26 @@ __kernel_clock_gettime:
|
||||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,2f
|
||||
ahi %r0,-1
|
||||
2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
2: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
lr %r2,%r0
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
l %r0,__VDSO_TK_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 3f
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
a %r0,__VDSO_TK_MULT(%r5)
|
||||
3: alr %r0,%r2
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
|
||||
al %r1,__VDSO_XTIME_NSEC+4(%r5)
|
||||
brc 12,4f
|
||||
ahi %r0,1
|
||||
4: l %r2,__VDSO_XTIME_SEC+4(%r5)
|
||||
al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
|
||||
4: al %r0,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
|
||||
al %r1,__VDSO_WTOM_NSEC+4(%r5)
|
||||
brc 12,5f
|
||||
ahi %r0,1
|
||||
5: al %r2,__VDSO_WTOM_SEC+4(%r5)
|
||||
5: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
srdl %r0,0(%r2) /* >> tk->shift */
|
||||
l %r2,__VDSO_XTIME_SEC+4(%r5)
|
||||
al %r2,__VDSO_WTOM_SEC+4(%r5)
|
||||
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
|
||||
jne 1b
|
||||
basr %r5,0
|
||||
@ -86,20 +87,21 @@ __kernel_clock_gettime:
|
||||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,12f
|
||||
ahi %r0,-1
|
||||
12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
12: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
lr %r2,%r0
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
l %r0,__VDSO_TK_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 13f
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
a %r0,__VDSO_TK_MULT(%r5)
|
||||
13: alr %r0,%r2
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
|
||||
al %r1,__VDSO_XTIME_NSEC+4(%r5)
|
||||
brc 12,14f
|
||||
ahi %r0,1
|
||||
14: l %r2,__VDSO_XTIME_SEC+4(%r5)
|
||||
14: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
srdl %r0,0(%r2) /* >> tk->shift */
|
||||
l %r2,__VDSO_XTIME_SEC+4(%r5)
|
||||
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
|
||||
jne 11b
|
||||
basr %r5,0
|
||||
|
@ -35,15 +35,14 @@ __kernel_gettimeofday:
|
||||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,3f
|
||||
ahi %r0,-1
|
||||
3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
3: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
st %r0,24(%r15)
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
l %r0,__VDSO_TK_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 4f
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
a %r0,__VDSO_TK_MULT(%r5)
|
||||
4: al %r0,24(%r15)
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
al %r1,__VDSO_XTIME_NSEC+4(%r5)
|
||||
brc 12,5f
|
||||
@ -51,6 +50,8 @@ __kernel_gettimeofday:
|
||||
5: mvc 24(4,%r15),__VDSO_XTIME_SEC+4(%r5)
|
||||
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
|
||||
jne 1b
|
||||
l %r4,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
srdl %r0,0(%r4) /* >> tk->shift */
|
||||
l %r4,24(%r15) /* get tv_sec from stack */
|
||||
basr %r5,0
|
||||
6: ltr %r0,%r0
|
||||
|
@ -34,14 +34,15 @@ __kernel_clock_gettime:
|
||||
tmll %r4,0x0001 /* pending update ? loop */
|
||||
jnz 0b
|
||||
stck 48(%r15) /* Store TOD clock */
|
||||
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
|
||||
alg %r0,__VDSO_WTOM_SEC(%r5) /* + wall_to_monotonic.sec */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5)
|
||||
alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
|
||||
alg %r0,__VDSO_WTOM_SEC(%r5)
|
||||
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
|
||||
alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic.nsec */
|
||||
srlg %r1,%r1,0(%r2) /* >> tk->shift */
|
||||
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
|
||||
jne 0b
|
||||
larl %r5,13f
|
||||
@ -62,12 +63,13 @@ __kernel_clock_gettime:
|
||||
tmll %r4,0x0001 /* pending update ? loop */
|
||||
jnz 5b
|
||||
stck 48(%r15) /* Store TOD clock */
|
||||
lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5)
|
||||
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
|
||||
srlg %r1,%r1,0(%r2) /* >> tk->shift */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
|
||||
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
|
||||
jne 5b
|
||||
larl %r5,13f
|
||||
|
@ -31,12 +31,13 @@ __kernel_gettimeofday:
|
||||
stck 48(%r15) /* Store TOD clock */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
|
||||
msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */
|
||||
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
|
||||
jne 0b
|
||||
lgf %r5,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */
|
||||
srlg %r1,%r1,0(%r5) /* >> tk->shift */
|
||||
larl %r5,5f
|
||||
2: clg %r1,0(%r5)
|
||||
jl 3f
|
||||
|
@ -78,11 +78,14 @@ static size_t copy_in_kernel(size_t count, void __user *to,
|
||||
* contains the (negative) exception code.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
static unsigned long follow_table(struct mm_struct *mm,
|
||||
unsigned long address, int write)
|
||||
{
|
||||
unsigned long *table = (unsigned long *)__pa(mm->pgd);
|
||||
|
||||
if (unlikely(address > mm->context.asce_limit - 1))
|
||||
return -0x38UL;
|
||||
switch (mm->context.asce_bits & _ASCE_TYPE_MASK) {
|
||||
case _ASCE_TYPE_REGION1:
|
||||
table = table + ((address >> 53) & 0x7ff);
|
||||
|
@ -33,12 +33,11 @@ MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas
|
||||
|
||||
HEADER_ARCH := $(SUBARCH)
|
||||
|
||||
# Additional ARCH settings for x86
|
||||
ifeq ($(SUBARCH),i386)
|
||||
HEADER_ARCH := x86
|
||||
ifneq ($(filter $(SUBARCH),x86 x86_64 i386),)
|
||||
HEADER_ARCH := x86
|
||||
endif
|
||||
ifeq ($(SUBARCH),x86_64)
|
||||
HEADER_ARCH := x86
|
||||
|
||||
ifdef CONFIG_64BIT
|
||||
KBUILD_CFLAGS += -mcmodel=large
|
||||
endif
|
||||
|
||||
|
@ -19,7 +19,7 @@ struct stack_frame {
|
||||
unsigned long return_address;
|
||||
};
|
||||
|
||||
static void print_stack_trace(unsigned long *sp, unsigned long bp)
|
||||
static void do_stack_trace(unsigned long *sp, unsigned long bp)
|
||||
{
|
||||
int reliable;
|
||||
unsigned long addr;
|
||||
@ -94,5 +94,5 @@ void show_stack(struct task_struct *task, unsigned long *stack)
|
||||
}
|
||||
printk(KERN_CONT "\n");
|
||||
|
||||
print_stack_trace(sp, bp);
|
||||
do_stack_trace(sp, bp);
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ ifeq ($(CONFIG_X86_32),y)
|
||||
|
||||
KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return
|
||||
|
||||
# Don't autogenerate SSE instructions
|
||||
KBUILD_CFLAGS += -mno-sse
|
||||
|
||||
# Never want PIC in a 32-bit kernel, prevent breakage with GCC built
|
||||
# with nonstandard options
|
||||
KBUILD_CFLAGS += -fno-pic
|
||||
@ -57,8 +60,11 @@ else
|
||||
KBUILD_AFLAGS += -m64
|
||||
KBUILD_CFLAGS += -m64
|
||||
|
||||
# Don't autogenerate SSE instructions
|
||||
KBUILD_CFLAGS += -mno-sse
|
||||
|
||||
# Use -mpreferred-stack-boundary=3 if supported.
|
||||
KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3)
|
||||
KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
|
||||
|
||||
# FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
|
||||
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
|
||||
|
@ -3,8 +3,9 @@
|
||||
#
|
||||
|
||||
avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
|
||||
avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
|
||||
$(comma)4)$(comma)%ymm2,yes,no)
|
||||
|
||||
obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o
|
||||
obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/crypto/aes.h>
|
||||
#include <asm/crypto/ablk_helper.h>
|
||||
#include <crypto/ablk_helper.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/internal/aead.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user