forked from Minki/linux
Few fixes for omaps to enable NAND BCH so devices won't
produce errors when booted with omap2plus_defconfig, and reduce bloat by making IPV6 a loadable module. Also let's add a warning about legacy boot being deprecated for omap3. We now have things working with device tree, and only omap3 is still booting in legacy mode. So hopefully this warning will help move the remaining legacy mode users to boot with device tree. As the total reduction of code and static data is somewhere around 20000 lines of code once we remove omap3 legacy mode booting, we really do want to make omap3 to boot also in device tree mode only over the next few merge cycles. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUUmuGAAoJEBvUPslcq6VzcvkQAJkQhYXffP+lN8XHvZKNSnXb aue3W1PBI9zPwnMfySryo/262od/cz1ucgLwNn7SHFs2EhfEYNKSjgF++q+ave8q frqwbEE0Pe5dGlV9tmA6SdffsiW2hLPuI1XF9a1XBW2qD5LHBidJLconUILnQsH2 E7ddhf2K/yAizF3BRhOeX7YVzOG5hxodBuhPz1fqLllfTA3EBXgB33wffHSOGVls r1fgpaUFzaBoJ5ZZyqNx7chGBRrOxAOviz/zvp8ljFkCelENkBa8IkuSiNRbiWlk el4wo3HfCRypqKBpXlDkD6Gfkugvc54xmkXXod/qgNnFchaIR0LENuzNonHZlC2S cIVGuqIhRaIHkLMtJKATH13WmA7MqYg3Vcjqm5VnVpaqM6Q4390Ug000UpLj7FEB 6FXnN3tQJLBgmvc5SDhohXNzWZSjXGTUBo92fS9zc4BzN9CUrLsEfKZtIcHA7HSZ rseGiLx0dyrYPdwsyEfp1row/ZWw9fGbtWCumN1LXlnQH/IXwGGf+irOeKbMmU2V nRZxpQIQtEfpJTJf0lKMZV7JUm93MXOvkcMPaPq9PtEn0plC7YIohPrO/yEPdl9K EIuehWwRbbjWoxtznTLlm9FOwNBg/PtChq6XP+M+wHzeDfiumA3jwPQEtmUkhha3 wy42f5Bi3MhtIzZ51oDm =WvgB -----END PGP SIGNATURE----- Merge tag 'fixes-against-v3.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes Merge "omap fixes against v3.18-rc2" from Tony Lindgren: Few fixes for omaps to enable NAND BCH so devices won't produce errors when booted with omap2plus_defconfig, and reduce bloat by making IPV6 a loadable module. Also let's add a warning about legacy boot being deprecated for omap3. We now have things working with device tree, and only omap3 is still booting in legacy mode. So hopefully this warning will help move the remaining legacy mode users to boot with device tree. As the total reduction of code and static data is somewhere around 20000 lines of code once we remove omap3 legacy mode booting, we really do want to make omap3 to boot also in device tree mode only over the next few merge cycles. * tag 'fixes-against-v3.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (407 commits) ARM: OMAP2+: Warn about deprecated legacy booting mode ARM: omap2plus_defconfig: Fix errors with NAND BCH ARM: omap2plus_defconfig: Fix bloat caused by having ipv6 built-in + Linux 3.18-rc2 Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
4257412db5
@ -17,7 +17,7 @@ User addresses have bits 63:48 set to 0 while the kernel addresses have
|
||||
the same bits set to 1. TTBRx selection is given by bit 63 of the
|
||||
virtual address. The swapper_pg_dir contains only kernel (global)
|
||||
mappings while the user pgd contains only user (non-global) mappings.
|
||||
The swapper_pgd_dir address is written to TTBR1 and never written to
|
||||
The swapper_pg_dir address is written to TTBR1 and never written to
|
||||
TTBR0.
|
||||
|
||||
|
||||
|
38
Documentation/devicetree/bindings/mailbox/mailbox.txt
Normal file
38
Documentation/devicetree/bindings/mailbox/mailbox.txt
Normal file
@ -0,0 +1,38 @@
|
||||
* Generic Mailbox Controller and client driver bindings
|
||||
|
||||
Generic binding to provide a way for Mailbox controller drivers to
|
||||
assign appropriate mailbox channel to client drivers.
|
||||
|
||||
* Mailbox Controller
|
||||
|
||||
Required property:
|
||||
- #mbox-cells: Must be at least 1. Number of cells in a mailbox
|
||||
specifier.
|
||||
|
||||
Example:
|
||||
mailbox: mailbox {
|
||||
...
|
||||
#mbox-cells = <1>;
|
||||
};
|
||||
|
||||
|
||||
* Mailbox Client
|
||||
|
||||
Required property:
|
||||
- mboxes: List of phandle and mailbox channel specifiers.
|
||||
|
||||
Optional property:
|
||||
- mbox-names: List of identifier strings for each mailbox channel
|
||||
required by the client. The use of this property
|
||||
is discouraged in favor of using index in list of
|
||||
'mboxes' while requesting a mailbox. Instead the
|
||||
platforms may define channel indices, in DT headers,
|
||||
to something legible.
|
||||
|
||||
Example:
|
||||
pwr_cntrl: power {
|
||||
...
|
||||
mbox-names = "pwr-ctrl", "rpc";
|
||||
mboxes = <&mailbox 0
|
||||
&mailbox 1>;
|
||||
};
|
@ -1,5 +1,20 @@
|
||||
Freescale FlexTimer Module (FTM) PWM controller
|
||||
|
||||
The same FTM PWM device can have a different endianness on different SoCs. The
|
||||
device tree provides a property to describing this so that an operating system
|
||||
device driver can handle all variants of the device. Refer to the table below
|
||||
for the endianness of the FTM PWM block as integrated into the existing SoCs:
|
||||
|
||||
SoC | FTM-PWM endianness
|
||||
--------+-------------------
|
||||
Vybrid | LE
|
||||
LS1 | BE
|
||||
LS2 | LE
|
||||
|
||||
Please see ../regmap/regmap.txt for more detail about how to specify endian
|
||||
modes in device tree.
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,vf610-ftm-pwm".
|
||||
- reg: Physical base address and length of the controller's registers
|
||||
@ -16,7 +31,8 @@ Required properties:
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
|
||||
See pinctrl/pinctrl-bindings.txt for details of the property values.
|
||||
|
||||
- big-endian: Boolean property, required if the FTM PWM registers use a big-
|
||||
endian rather than little-endian layout.
|
||||
|
||||
Example:
|
||||
|
||||
@ -32,4 +48,5 @@ pwm0: pwm@40038000 {
|
||||
<&clks VF610_CLK_FTM0_EXT_FIX_EN>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pwm0_1>;
|
||||
big-endian;
|
||||
};
|
||||
|
@ -7,8 +7,8 @@ Required properties:
|
||||
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
|
||||
- reg: physical base address and length of the controller's registers
|
||||
- clocks: phandle and clock specifier of the PWM reference clock
|
||||
- #pwm-cells: should be 2. See pwm.txt in this directory for a
|
||||
description of the cell format.
|
||||
- #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
|
||||
for a description of the cell format.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
* Temperature Monitor (TEMPMON) on Freescale i.MX SoCs
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx6q-thermal"
|
||||
- compatible : "fsl,imx6q-tempmon" for i.MX6Q, "fsl,imx6sx-tempmon" for i.MX6SX.
|
||||
i.MX6SX has two more IRQs than i.MX6Q, one is IRQ_LOW and the other is IRQ_PANIC,
|
||||
when temperature is below than low threshold, IRQ_LOW will be triggered, when temperature
|
||||
is higher than panic threshold, system will auto reboot by SRC module.
|
||||
- fsl,tempmon : phandle pointer to system controller that contains TEMPMON
|
||||
control registers, e.g. ANATOP on imx6q.
|
||||
- fsl,tempmon-data : phandle pointer to fuse controller that contains TEMPMON
|
||||
|
24
Documentation/devicetree/bindings/watchdog/cadence-wdt.txt
Normal file
24
Documentation/devicetree/bindings/watchdog/cadence-wdt.txt
Normal file
@ -0,0 +1,24 @@
|
||||
Zynq Watchdog Device Tree Bindings
|
||||
-------------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "cdns,wdt-r1p2".
|
||||
- clocks : This is pclk (APB clock).
|
||||
- interrupts : This is wd_irq - watchdog timeout interrupt.
|
||||
- interrupt-parent : Must be core interrupt controller.
|
||||
|
||||
Optional properties
|
||||
- reset-on-timeout : If this property exists, then a reset is done
|
||||
when watchdog times out.
|
||||
- timeout-sec : Watchdog timeout value (in seconds).
|
||||
|
||||
Example:
|
||||
watchdog@f8005000 {
|
||||
compatible = "cdns,wdt-r1p2";
|
||||
clocks = <&clkc 45>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 9 1>;
|
||||
reg = <0xf8005000 0x1000>;
|
||||
reset-on-timeout;
|
||||
timeout-sec = <10>;
|
||||
};
|
@ -7,7 +7,8 @@ Required properties:
|
||||
|
||||
Optional property:
|
||||
- big-endian: If present the watchdog device's registers are implemented
|
||||
in big endian mode, otherwise in little mode.
|
||||
in big endian mode, otherwise in native mode(same with CPU), for more
|
||||
detail please see: Documentation/devicetree/bindings/regmap/regmap.txt.
|
||||
|
||||
Examples:
|
||||
|
||||
|
13
Documentation/devicetree/bindings/watchdog/meson6-wdt.txt
Normal file
13
Documentation/devicetree/bindings/watchdog/meson6-wdt.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Meson SoCs Watchdog timer
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "amlogic,meson6-wdt"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
|
||||
Example:
|
||||
|
||||
wdt: watchdog@c1109900 {
|
||||
compatible = "amlogic,meson6-wdt";
|
||||
reg = <0xc1109900 0x8>;
|
||||
};
|
24
Documentation/devicetree/bindings/watchdog/qcom-wdt.txt
Normal file
24
Documentation/devicetree/bindings/watchdog/qcom-wdt.txt
Normal file
@ -0,0 +1,24 @@
|
||||
Qualcomm Krait Processor Sub-system (KPSS) Watchdog
|
||||
---------------------------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible : shall contain only one of the following:
|
||||
|
||||
"qcom,kpss-wdt-msm8960"
|
||||
"qcom,kpss-wdt-apq8064"
|
||||
"qcom,kpss-wdt-ipq8064"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
- clocks : shall contain the input clock
|
||||
|
||||
Optional properties :
|
||||
- timeout-sec : shall contain the default watchdog timeout in seconds,
|
||||
if unset, the default timeout is 30 seconds
|
||||
|
||||
Example:
|
||||
watchdog@208a038 {
|
||||
compatible = "qcom,kpss-wdt-ipq8064";
|
||||
reg = <0x0208a038 0x40>;
|
||||
clocks = <&sleep_clk>;
|
||||
timeout-sec = <10>;
|
||||
};
|
@ -9,6 +9,7 @@ Required properties:
|
||||
(a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs
|
||||
(b) "samsung,exynos5250-wdt" for Exynos5250
|
||||
(c) "samsung,exynos5420-wdt" for Exynos5420
|
||||
(c) "samsung,exynos7-wdt" for Exynos7
|
||||
|
||||
- reg : base physical address of the controller and length of memory mapped
|
||||
region.
|
||||
|
@ -67,6 +67,7 @@ prototypes:
|
||||
struct file *, unsigned open_flag,
|
||||
umode_t create_mode, int *opened);
|
||||
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
|
||||
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
|
||||
|
||||
locking rules:
|
||||
all may block
|
||||
@ -96,6 +97,7 @@ fiemap: no
|
||||
update_time: no
|
||||
atomic_open: yes
|
||||
tmpfile: no
|
||||
dentry_open: no
|
||||
|
||||
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
|
||||
victim.
|
||||
|
198
Documentation/filesystems/overlayfs.txt
Normal file
198
Documentation/filesystems/overlayfs.txt
Normal file
@ -0,0 +1,198 @@
|
||||
Written by: Neil Brown <neilb@suse.de>
|
||||
|
||||
Overlay Filesystem
|
||||
==================
|
||||
|
||||
This document describes a prototype for a new approach to providing
|
||||
overlay-filesystem functionality in Linux (sometimes referred to as
|
||||
union-filesystems). An overlay-filesystem tries to present a
|
||||
filesystem which is the result over overlaying one filesystem on top
|
||||
of the other.
|
||||
|
||||
The result will inevitably fail to look exactly like a normal
|
||||
filesystem for various technical reasons. The expectation is that
|
||||
many use cases will be able to ignore these differences.
|
||||
|
||||
This approach is 'hybrid' because the objects that appear in the
|
||||
filesystem do not all appear to belong to that filesystem. In many
|
||||
cases an object accessed in the union will be indistinguishable
|
||||
from accessing the corresponding object from the original filesystem.
|
||||
This is most obvious from the 'st_dev' field returned by stat(2).
|
||||
|
||||
While directories will report an st_dev from the overlay-filesystem,
|
||||
all non-directory objects will report an st_dev from the lower or
|
||||
upper filesystem that is providing the object. Similarly st_ino will
|
||||
only be unique when combined with st_dev, and both of these can change
|
||||
over the lifetime of a non-directory object. Many applications and
|
||||
tools ignore these values and will not be affected.
|
||||
|
||||
Upper and Lower
|
||||
---------------
|
||||
|
||||
An overlay filesystem combines two filesystems - an 'upper' filesystem
|
||||
and a 'lower' filesystem. When a name exists in both filesystems, the
|
||||
object in the 'upper' filesystem is visible while the object in the
|
||||
'lower' filesystem is either hidden or, in the case of directories,
|
||||
merged with the 'upper' object.
|
||||
|
||||
It would be more correct to refer to an upper and lower 'directory
|
||||
tree' rather than 'filesystem' as it is quite possible for both
|
||||
directory trees to be in the same filesystem and there is no
|
||||
requirement that the root of a filesystem be given for either upper or
|
||||
lower.
|
||||
|
||||
The lower filesystem can be any filesystem supported by Linux and does
|
||||
not need to be writable. The lower filesystem can even be another
|
||||
overlayfs. The upper filesystem will normally be writable and if it
|
||||
is it must support the creation of trusted.* extended attributes, and
|
||||
must provide valid d_type in readdir responses, so NFS is not suitable.
|
||||
|
||||
A read-only overlay of two read-only filesystems may use any
|
||||
filesystem type.
|
||||
|
||||
Directories
|
||||
-----------
|
||||
|
||||
Overlaying mainly involves directories. If a given name appears in both
|
||||
upper and lower filesystems and refers to a non-directory in either,
|
||||
then the lower object is hidden - the name refers only to the upper
|
||||
object.
|
||||
|
||||
Where both upper and lower objects are directories, a merged directory
|
||||
is formed.
|
||||
|
||||
At mount time, the two directories given as mount options "lowerdir" and
|
||||
"upperdir" are combined into a merged directory:
|
||||
|
||||
mount -t overlayfs overlayfs -olowerdir=/lower,upperdir=/upper,\
|
||||
workdir=/work /merged
|
||||
|
||||
The "workdir" needs to be an empty directory on the same filesystem
|
||||
as upperdir.
|
||||
|
||||
Then whenever a lookup is requested in such a merged directory, the
|
||||
lookup is performed in each actual directory and the combined result
|
||||
is cached in the dentry belonging to the overlay filesystem. If both
|
||||
actual lookups find directories, both are stored and a merged
|
||||
directory is created, otherwise only one is stored: the upper if it
|
||||
exists, else the lower.
|
||||
|
||||
Only the lists of names from directories are merged. Other content
|
||||
such as metadata and extended attributes are reported for the upper
|
||||
directory only. These attributes of the lower directory are hidden.
|
||||
|
||||
whiteouts and opaque directories
|
||||
--------------------------------
|
||||
|
||||
In order to support rm and rmdir without changing the lower
|
||||
filesystem, an overlay filesystem needs to record in the upper filesystem
|
||||
that files have been removed. This is done using whiteouts and opaque
|
||||
directories (non-directories are always opaque).
|
||||
|
||||
A whiteout is created as a character device with 0/0 device number.
|
||||
When a whiteout is found in the upper level of a merged directory, any
|
||||
matching name in the lower level is ignored, and the whiteout itself
|
||||
is also hidden.
|
||||
|
||||
A directory is made opaque by setting the xattr "trusted.overlay.opaque"
|
||||
to "y". Where the upper filesystem contains an opaque directory, any
|
||||
directory in the lower filesystem with the same name is ignored.
|
||||
|
||||
readdir
|
||||
-------
|
||||
|
||||
When a 'readdir' request is made on a merged directory, the upper and
|
||||
lower directories are each read and the name lists merged in the
|
||||
obvious way (upper is read first, then lower - entries that already
|
||||
exist are not re-added). This merged name list is cached in the
|
||||
'struct file' and so remains as long as the file is kept open. If the
|
||||
directory is opened and read by two processes at the same time, they
|
||||
will each have separate caches. A seekdir to the start of the
|
||||
directory (offset 0) followed by a readdir will cause the cache to be
|
||||
discarded and rebuilt.
|
||||
|
||||
This means that changes to the merged directory do not appear while a
|
||||
directory is being read. This is unlikely to be noticed by many
|
||||
programs.
|
||||
|
||||
seek offsets are assigned sequentially when the directories are read.
|
||||
Thus if
|
||||
- read part of a directory
|
||||
- remember an offset, and close the directory
|
||||
- re-open the directory some time later
|
||||
- seek to the remembered offset
|
||||
|
||||
there may be little correlation between the old and new locations in
|
||||
the list of filenames, particularly if anything has changed in the
|
||||
directory.
|
||||
|
||||
Readdir on directories that are not merged is simply handled by the
|
||||
underlying directory (upper or lower).
|
||||
|
||||
|
||||
Non-directories
|
||||
---------------
|
||||
|
||||
Objects that are not directories (files, symlinks, device-special
|
||||
files etc.) are presented either from the upper or lower filesystem as
|
||||
appropriate. When a file in the lower filesystem is accessed in a way
|
||||
the requires write-access, such as opening for write access, changing
|
||||
some metadata etc., the file is first copied from the lower filesystem
|
||||
to the upper filesystem (copy_up). Note that creating a hard-link
|
||||
also requires copy_up, though of course creation of a symlink does
|
||||
not.
|
||||
|
||||
The copy_up may turn out to be unnecessary, for example if the file is
|
||||
opened for read-write but the data is not modified.
|
||||
|
||||
The copy_up process first makes sure that the containing directory
|
||||
exists in the upper filesystem - creating it and any parents as
|
||||
necessary. It then creates the object with the same metadata (owner,
|
||||
mode, mtime, symlink-target etc.) and then if the object is a file, the
|
||||
data is copied from the lower to the upper filesystem. Finally any
|
||||
extended attributes are copied up.
|
||||
|
||||
Once the copy_up is complete, the overlay filesystem simply
|
||||
provides direct access to the newly created file in the upper
|
||||
filesystem - future operations on the file are barely noticed by the
|
||||
overlay filesystem (though an operation on the name of the file such as
|
||||
rename or unlink will of course be noticed and handled).
|
||||
|
||||
|
||||
Non-standard behavior
|
||||
---------------------
|
||||
|
||||
The copy_up operation essentially creates a new, identical file and
|
||||
moves it over to the old name. The new file may be on a different
|
||||
filesystem, so both st_dev and st_ino of the file may change.
|
||||
|
||||
Any open files referring to this inode will access the old data and
|
||||
metadata. Similarly any file locks obtained before copy_up will not
|
||||
apply to the copied up file.
|
||||
|
||||
On a file opened with O_RDONLY fchmod(2), fchown(2), futimesat(2) and
|
||||
fsetxattr(2) will fail with EROFS.
|
||||
|
||||
If a file with multiple hard links is copied up, then this will
|
||||
"break" the link. Changes will not be propagated to other names
|
||||
referring to the same inode.
|
||||
|
||||
Symlinks in /proc/PID/ and /proc/PID/fd which point to a non-directory
|
||||
object in overlayfs will not contain valid absolute paths, only
|
||||
relative paths leading up to the filesystem's root. This will be
|
||||
fixed in the future.
|
||||
|
||||
Some operations are not atomic, for example a crash during copy_up or
|
||||
rename will leave the filesystem in an inconsistent state. This will
|
||||
be addressed in the future.
|
||||
|
||||
Changes to underlying filesystems
|
||||
---------------------------------
|
||||
|
||||
Offline changes, when the overlay is not mounted, are allowed to either
|
||||
the upper or the lower trees.
|
||||
|
||||
Changes to the underlying filesystems while part of a mounted overlay
|
||||
filesystem are not allowed. If the underlying filesystem is changed,
|
||||
the behavior of the overlay is undefined, though it will not result in
|
||||
a crash or deadlock.
|
@ -364,6 +364,7 @@ struct inode_operations {
|
||||
int (*atomic_open)(struct inode *, struct dentry *, struct file *,
|
||||
unsigned open_flag, umode_t create_mode, int *opened);
|
||||
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
|
||||
int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
|
||||
};
|
||||
|
||||
Again, all methods are called without any locks being held, unless
|
||||
@ -696,6 +697,12 @@ struct address_space_operations {
|
||||
but instead uses bmap to find out where the blocks in the file
|
||||
are and uses those addresses directly.
|
||||
|
||||
dentry_open: *WARNING: probably going away soon, do not use!* This is an
|
||||
alternative to f_op->open(), the difference is that this method may open
|
||||
a file not necessarily originating from the same filesystem as the one
|
||||
i_op->open() was called on. It may be useful for stacking filesystems
|
||||
which want to allow native I/O directly on underlying files.
|
||||
|
||||
|
||||
invalidatepage: If a page has PagePrivate set, then invalidatepage
|
||||
will be called when part or all of the page is to be removed
|
||||
|
@ -1015,10 +1015,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
Format: {"off" | "on" | "skip[mbr]"}
|
||||
|
||||
efi= [EFI]
|
||||
Format: { "old_map" }
|
||||
Format: { "old_map", "nochunk", "noruntime" }
|
||||
old_map [X86-64]: switch to the old ioremap-based EFI
|
||||
runtime services mapping. 32-bit still uses this one by
|
||||
default.
|
||||
nochunk: disable reading files in "chunks" in the EFI
|
||||
boot stub, as chunking can cause problems with some
|
||||
firmware implementations.
|
||||
noruntime : disable EFI runtime services support
|
||||
|
||||
efi_no_storage_paranoia [EFI; X86]
|
||||
Using this parameter you can use more than 50% of
|
||||
@ -2232,7 +2236,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
|
||||
nodsp [SH] Disable hardware DSP at boot time.
|
||||
|
||||
noefi [X86] Disable EFI runtime services support.
|
||||
noefi Disable EFI runtime services support.
|
||||
|
||||
noexec [IA-64]
|
||||
|
||||
@ -3465,6 +3469,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
e.g. base its process migration decisions on it.
|
||||
Default is on.
|
||||
|
||||
topology_updates= [KNL, PPC, NUMA]
|
||||
Format: {off}
|
||||
Specify if the kernel should ignore (off)
|
||||
topology updates sent by the hypervisor to this
|
||||
LPAR.
|
||||
|
||||
tp720= [HW,PS2]
|
||||
|
||||
tpm_suspend_pcr=[HW,TPM]
|
||||
|
122
Documentation/mailbox.txt
Normal file
122
Documentation/mailbox.txt
Normal file
@ -0,0 +1,122 @@
|
||||
The Common Mailbox Framework
|
||||
Jassi Brar <jaswinder.singh@linaro.org>
|
||||
|
||||
This document aims to help developers write client and controller
|
||||
drivers for the API. But before we start, let us note that the
|
||||
client (especially) and controller drivers are likely going to be
|
||||
very platform specific because the remote firmware is likely to be
|
||||
proprietary and implement non-standard protocol. So even if two
|
||||
platforms employ, say, PL320 controller, the client drivers can't
|
||||
be shared across them. Even the PL320 driver might need to accommodate
|
||||
some platform specific quirks. So the API is meant mainly to avoid
|
||||
similar copies of code written for each platform. Having said that,
|
||||
nothing prevents the remote f/w to also be Linux based and use the
|
||||
same api there. However none of that helps us locally because we only
|
||||
ever deal at client's protocol level.
|
||||
Some of the choices made during implementation are the result of this
|
||||
peculiarity of this "common" framework.
|
||||
|
||||
|
||||
|
||||
Part 1 - Controller Driver (See include/linux/mailbox_controller.h)
|
||||
|
||||
Allocate mbox_controller and the array of mbox_chan.
|
||||
Populate mbox_chan_ops, except peek_data() all are mandatory.
|
||||
The controller driver might know a message has been consumed
|
||||
by the remote by getting an IRQ or polling some hardware flag
|
||||
or it can never know (the client knows by way of the protocol).
|
||||
The method in order of preference is IRQ -> Poll -> None, which
|
||||
the controller driver should set via 'txdone_irq' or 'txdone_poll'
|
||||
or neither.
|
||||
|
||||
|
||||
Part 2 - Client Driver (See include/linux/mailbox_client.h)
|
||||
|
||||
The client might want to operate in blocking mode (synchronously
|
||||
send a message through before returning) or non-blocking/async mode (submit
|
||||
a message and a callback function to the API and return immediately).
|
||||
|
||||
|
||||
struct demo_client {
|
||||
struct mbox_client cl;
|
||||
struct mbox_chan *mbox;
|
||||
struct completion c;
|
||||
bool async;
|
||||
/* ... */
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the handler for data received from remote. The behaviour is purely
|
||||
* dependent upon the protocol. This is just an example.
|
||||
*/
|
||||
static void message_from_remote(struct mbox_client *cl, void *mssg)
|
||||
{
|
||||
struct demo_client *dc = container_of(mbox_client,
|
||||
struct demo_client, cl);
|
||||
if (dc->aysnc) {
|
||||
if (is_an_ack(mssg)) {
|
||||
/* An ACK to our last sample sent */
|
||||
return; /* Or do something else here */
|
||||
} else { /* A new message from remote */
|
||||
queue_req(mssg);
|
||||
}
|
||||
} else {
|
||||
/* Remote f/w sends only ACK packets on this channel */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void sample_sent(struct mbox_client *cl, void *mssg, int r)
|
||||
{
|
||||
struct demo_client *dc = container_of(mbox_client,
|
||||
struct demo_client, cl);
|
||||
complete(&dc->c);
|
||||
}
|
||||
|
||||
static void client_demo(struct platform_device *pdev)
|
||||
{
|
||||
struct demo_client *dc_sync, *dc_async;
|
||||
/* The controller already knows async_pkt and sync_pkt */
|
||||
struct async_pkt ap;
|
||||
struct sync_pkt sp;
|
||||
|
||||
dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
|
||||
dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
|
||||
|
||||
/* Populate non-blocking mode client */
|
||||
dc_async->cl.dev = &pdev->dev;
|
||||
dc_async->cl.rx_callback = message_from_remote;
|
||||
dc_async->cl.tx_done = sample_sent;
|
||||
dc_async->cl.tx_block = false;
|
||||
dc_async->cl.tx_tout = 0; /* doesn't matter here */
|
||||
dc_async->cl.knows_txdone = false; /* depending upon protocol */
|
||||
dc_async->async = true;
|
||||
init_completion(&dc_async->c);
|
||||
|
||||
/* Populate blocking mode client */
|
||||
dc_sync->cl.dev = &pdev->dev;
|
||||
dc_sync->cl.rx_callback = message_from_remote;
|
||||
dc_sync->cl.tx_done = NULL; /* operate in blocking mode */
|
||||
dc_sync->cl.tx_block = true;
|
||||
dc_sync->cl.tx_tout = 500; /* by half a second */
|
||||
dc_sync->cl.knows_txdone = false; /* depending upon protocol */
|
||||
dc_sync->async = false;
|
||||
|
||||
/* ASync mailbox is listed second in 'mboxes' property */
|
||||
dc_async->mbox = mbox_request_channel(&dc_async->cl, 1);
|
||||
/* Populate data packet */
|
||||
/* ap.xxx = 123; etc */
|
||||
/* Send async message to remote */
|
||||
mbox_send_message(dc_async->mbox, &ap);
|
||||
|
||||
/* Sync mailbox is listed first in 'mboxes' property */
|
||||
dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
|
||||
/* Populate data packet */
|
||||
/* sp.abc = 123; etc */
|
||||
/* Send message to remote in blocking mode */
|
||||
mbox_send_message(dc_sync->mbox, &sp);
|
||||
/* At this point 'sp' has been sent */
|
||||
|
||||
/* Now wait for async chan to be done */
|
||||
wait_for_completion(&dc_async->c);
|
||||
}
|
@ -5,7 +5,8 @@ performance expectations by drivers, subsystems and user space applications on
|
||||
one of the parameters.
|
||||
|
||||
Two different PM QoS frameworks are available:
|
||||
1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput.
|
||||
1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput,
|
||||
memory_bandwidth.
|
||||
2. the per-device PM QoS framework provides the API to manage the per-device latency
|
||||
constraints and PM QoS flags.
|
||||
|
||||
@ -13,6 +14,7 @@ Each parameters have defined units:
|
||||
* latency: usec
|
||||
* timeout: usec
|
||||
* throughput: kbs (kilo bit / sec)
|
||||
* memory bandwidth: mbs (mega bit / sec)
|
||||
|
||||
|
||||
1. PM QoS framework
|
||||
|
@ -184,8 +184,7 @@ Any problems, questions, bug reports, lonely OSD nights, please email:
|
||||
More up-to-date information can be found on:
|
||||
http://open-osd.org
|
||||
|
||||
Boaz Harrosh <bharrosh@panasas.com>
|
||||
Benny Halevy <bhalevy@panasas.com>
|
||||
Boaz Harrosh <ooo@electrozaur.com>
|
||||
|
||||
References
|
||||
==========
|
||||
|
378
Documentation/target/tcmu-design.txt
Normal file
378
Documentation/target/tcmu-design.txt
Normal file
@ -0,0 +1,378 @@
|
||||
Contents:
|
||||
|
||||
1) TCM Userspace Design
|
||||
a) Background
|
||||
b) Benefits
|
||||
c) Design constraints
|
||||
d) Implementation overview
|
||||
i. Mailbox
|
||||
ii. Command ring
|
||||
iii. Data Area
|
||||
e) Device discovery
|
||||
f) Device events
|
||||
g) Other contingencies
|
||||
2) Writing a user pass-through handler
|
||||
a) Discovering and configuring TCMU uio devices
|
||||
b) Waiting for events on the device(s)
|
||||
c) Managing the command ring
|
||||
3) Command filtering and pass_level
|
||||
4) A final note
|
||||
|
||||
|
||||
TCM Userspace Design
|
||||
--------------------
|
||||
|
||||
TCM is another name for LIO, an in-kernel iSCSI target (server).
|
||||
Existing TCM targets run in the kernel. TCMU (TCM in Userspace)
|
||||
allows userspace programs to be written which act as iSCSI targets.
|
||||
This document describes the design.
|
||||
|
||||
The existing kernel provides modules for different SCSI transport
|
||||
protocols. TCM also modularizes the data storage. There are existing
|
||||
modules for file, block device, RAM or using another SCSI device as
|
||||
storage. These are called "backstores" or "storage engines". These
|
||||
built-in modules are implemented entirely as kernel code.
|
||||
|
||||
Background:
|
||||
|
||||
In addition to modularizing the transport protocol used for carrying
|
||||
SCSI commands ("fabrics"), the Linux kernel target, LIO, also modularizes
|
||||
the actual data storage as well. These are referred to as "backstores"
|
||||
or "storage engines". The target comes with backstores that allow a
|
||||
file, a block device, RAM, or another SCSI device to be used for the
|
||||
local storage needed for the exported SCSI LUN. Like the rest of LIO,
|
||||
these are implemented entirely as kernel code.
|
||||
|
||||
These backstores cover the most common use cases, but not all. One new
|
||||
use case that other non-kernel target solutions, such as tgt, are able
|
||||
to support is using Gluster's GLFS or Ceph's RBD as a backstore. The
|
||||
target then serves as a translator, allowing initiators to store data
|
||||
in these non-traditional networked storage systems, while still only
|
||||
using standard protocols themselves.
|
||||
|
||||
If the target is a userspace process, supporting these is easy. tgt,
|
||||
for example, needs only a small adapter module for each, because the
|
||||
modules just use the available userspace libraries for RBD and GLFS.
|
||||
|
||||
Adding support for these backstores in LIO is considerably more
|
||||
difficult, because LIO is entirely kernel code. Instead of undertaking
|
||||
the significant work to port the GLFS or RBD APIs and protocols to the
|
||||
kernel, another approach is to create a userspace pass-through
|
||||
backstore for LIO, "TCMU".
|
||||
|
||||
|
||||
Benefits:
|
||||
|
||||
In addition to allowing relatively easy support for RBD and GLFS, TCMU
|
||||
will also allow easier development of new backstores. TCMU combines
|
||||
with the LIO loopback fabric to become something similar to FUSE
|
||||
(Filesystem in Userspace), but at the SCSI layer instead of the
|
||||
filesystem layer. A SUSE, if you will.
|
||||
|
||||
The disadvantage is there are more distinct components to configure, and
|
||||
potentially to malfunction. This is unavoidable, but hopefully not
|
||||
fatal if we're careful to keep things as simple as possible.
|
||||
|
||||
Design constraints:
|
||||
|
||||
- Good performance: high throughput, low latency
|
||||
- Cleanly handle if userspace:
|
||||
1) never attaches
|
||||
2) hangs
|
||||
3) dies
|
||||
4) misbehaves
|
||||
- Allow future flexibility in user & kernel implementations
|
||||
- Be reasonably memory-efficient
|
||||
- Simple to configure & run
|
||||
- Simple to write a userspace backend
|
||||
|
||||
|
||||
Implementation overview:
|
||||
|
||||
The core of the TCMU interface is a memory region that is shared
|
||||
between kernel and userspace. Within this region is: a control area
|
||||
(mailbox); a lockless producer/consumer circular buffer for commands
|
||||
to be passed up, and status returned; and an in/out data buffer area.
|
||||
|
||||
TCMU uses the pre-existing UIO subsystem. UIO allows device driver
|
||||
development in userspace, and this is conceptually very close to the
|
||||
TCMU use case, except instead of a physical device, TCMU implements a
|
||||
memory-mapped layout designed for SCSI commands. Using UIO also
|
||||
benefits TCMU by handling device introspection (e.g. a way for
|
||||
userspace to determine how large the shared region is) and signaling
|
||||
mechanisms in both directions.
|
||||
|
||||
There are no embedded pointers in the memory region. Everything is
|
||||
expressed as an offset from the region's starting address. This allows
|
||||
the ring to still work if the user process dies and is restarted with
|
||||
the region mapped at a different virtual address.
|
||||
|
||||
See target_core_user.h for the struct definitions.
|
||||
|
||||
The Mailbox:
|
||||
|
||||
The mailbox is always at the start of the shared memory region, and
|
||||
contains a version, details about the starting offset and size of the
|
||||
command ring, and head and tail pointers to be used by the kernel and
|
||||
userspace (respectively) to put commands on the ring, and indicate
|
||||
when the commands are completed.
|
||||
|
||||
version - 1 (userspace should abort if otherwise)
|
||||
flags - none yet defined.
|
||||
cmdr_off - The offset of the start of the command ring from the start
|
||||
of the memory region, to account for the mailbox size.
|
||||
cmdr_size - The size of the command ring. This does *not* need to be a
|
||||
power of two.
|
||||
cmd_head - Modified by the kernel to indicate when a command has been
|
||||
placed on the ring.
|
||||
cmd_tail - Modified by userspace to indicate when it has completed
|
||||
processing of a command.
|
||||
|
||||
The Command Ring:
|
||||
|
||||
Commands are placed on the ring by the kernel incrementing
|
||||
mailbox.cmd_head by the size of the command, modulo cmdr_size, and
|
||||
then signaling userspace via uio_event_notify(). Once the command is
|
||||
completed, userspace updates mailbox.cmd_tail in the same way and
|
||||
signals the kernel via a 4-byte write(). When cmd_head equals
|
||||
cmd_tail, the ring is empty -- no commands are currently waiting to be
|
||||
processed by userspace.
|
||||
|
||||
TCMU commands start with a common header containing "len_op", a 32-bit
|
||||
value that stores the length, as well as the opcode in the lowest
|
||||
unused bits. Currently only two opcodes are defined, TCMU_OP_PAD and
|
||||
TCMU_OP_CMD. When userspace encounters a command with PAD opcode, it
|
||||
should skip ahead by the bytes in "length". (The kernel inserts PAD
|
||||
entries to ensure each CMD entry fits contigously into the circular
|
||||
buffer.)
|
||||
|
||||
When userspace handles a CMD, it finds the SCSI CDB (Command Data
|
||||
Block) via tcmu_cmd_entry.req.cdb_off. This is an offset from the
|
||||
start of the overall shared memory region, not the entry. The data
|
||||
in/out buffers are accessible via tht req.iov[] array. Note that
|
||||
each iov.iov_base is also an offset from the start of the region.
|
||||
|
||||
TCMU currently does not support BIDI operations.
|
||||
|
||||
When completing a command, userspace sets rsp.scsi_status, and
|
||||
rsp.sense_buffer if necessary. Userspace then increments
|
||||
mailbox.cmd_tail by entry.hdr.length (mod cmdr_size) and signals the
|
||||
kernel via the UIO method, a 4-byte write to the file descriptor.
|
||||
|
||||
The Data Area:
|
||||
|
||||
This is shared-memory space after the command ring. The organization
|
||||
of this area is not defined in the TCMU interface, and userspace
|
||||
should access only the parts referenced by pending iovs.
|
||||
|
||||
|
||||
Device Discovery:
|
||||
|
||||
Other devices may be using UIO besides TCMU. Unrelated user processes
|
||||
may also be handling different sets of TCMU devices. TCMU userspace
|
||||
processes must find their devices by scanning sysfs
|
||||
class/uio/uio*/name. For TCMU devices, these names will be of the
|
||||
format:
|
||||
|
||||
tcm-user/<hba_num>/<device_name>/<subtype>/<path>
|
||||
|
||||
where "tcm-user" is common for all TCMU-backed UIO devices. <hba_num>
|
||||
and <device_name> allow userspace to find the device's path in the
|
||||
kernel target's configfs tree. Assuming the usual mount point, it is
|
||||
found at:
|
||||
|
||||
/sys/kernel/config/target/core/user_<hba_num>/<device_name>
|
||||
|
||||
This location contains attributes such as "hw_block_size", that
|
||||
userspace needs to know for correct operation.
|
||||
|
||||
<subtype> will be a userspace-process-unique string to identify the
|
||||
TCMU device as expecting to be backed by a certain handler, and <path>
|
||||
will be an additional handler-specific string for the user process to
|
||||
configure the device, if needed. The name cannot contain ':', due to
|
||||
LIO limitations.
|
||||
|
||||
For all devices so discovered, the user handler opens /dev/uioX and
|
||||
calls mmap():
|
||||
|
||||
mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)
|
||||
|
||||
where size must be equal to the value read from
|
||||
/sys/class/uio/uioX/maps/map0/size.
|
||||
|
||||
|
||||
Device Events:
|
||||
|
||||
If a new device is added or removed, a notification will be broadcast
|
||||
over netlink, using a generic netlink family name of "TCM-USER" and a
|
||||
multicast group named "config". This will include the UIO name as
|
||||
described in the previous section, as well as the UIO minor
|
||||
number. This should allow userspace to identify both the UIO device and
|
||||
the LIO device, so that after determining the device is supported
|
||||
(based on subtype) it can take the appropriate action.
|
||||
|
||||
|
||||
Other contingencies:
|
||||
|
||||
Userspace handler process never attaches:
|
||||
|
||||
- TCMU will post commands, and then abort them after a timeout period
|
||||
(30 seconds.)
|
||||
|
||||
Userspace handler process is killed:
|
||||
|
||||
- It is still possible to restart and re-connect to TCMU
|
||||
devices. Command ring is preserved. However, after the timeout period,
|
||||
the kernel will abort pending tasks.
|
||||
|
||||
Userspace handler process hangs:
|
||||
|
||||
- The kernel will abort pending tasks after a timeout period.
|
||||
|
||||
Userspace handler process is malicious:
|
||||
|
||||
- The process can trivially break the handling of devices it controls,
|
||||
but should not be able to access kernel memory outside its shared
|
||||
memory areas.
|
||||
|
||||
|
||||
Writing a user pass-through handler (with example code)
|
||||
-------------------------------------------------------
|
||||
|
||||
A user process handing a TCMU device must support the following:
|
||||
|
||||
a) Discovering and configuring TCMU uio devices
|
||||
b) Waiting for events on the device(s)
|
||||
c) Managing the command ring: Parsing operations and commands,
|
||||
performing work as needed, setting response fields (scsi_status and
|
||||
possibly sense_buffer), updating cmd_tail, and notifying the kernel
|
||||
that work has been finished
|
||||
|
||||
First, consider instead writing a plugin for tcmu-runner. tcmu-runner
|
||||
implements all of this, and provides a higher-level API for plugin
|
||||
authors.
|
||||
|
||||
TCMU is designed so that multiple unrelated processes can manage TCMU
|
||||
devices separately. All handlers should make sure to only open their
|
||||
devices, based opon a known subtype string.
|
||||
|
||||
a) Discovering and configuring TCMU UIO devices:
|
||||
|
||||
(error checking omitted for brevity)
|
||||
|
||||
int fd, dev_fd;
|
||||
char buf[256];
|
||||
unsigned long long map_len;
|
||||
void *map;
|
||||
|
||||
fd = open("/sys/class/uio/uio0/name", O_RDONLY);
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
buf[ret-1] = '\0'; /* null-terminate and chop off the \n */
|
||||
|
||||
/* we only want uio devices whose name is a format we expect */
|
||||
if (strncmp(buf, "tcm-user", 8))
|
||||
exit(-1);
|
||||
|
||||
/* Further checking for subtype also needed here */
|
||||
|
||||
fd = open(/sys/class/uio/%s/maps/map0/size, O_RDONLY);
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
str_buf[ret-1] = '\0'; /* null-terminate and chop off the \n */
|
||||
|
||||
map_len = strtoull(buf, NULL, 0);
|
||||
|
||||
dev_fd = open("/dev/uio0", O_RDWR);
|
||||
map = mmap(NULL, map_len, PROT_READ|PROT_WRITE, MAP_SHARED, dev_fd, 0);
|
||||
|
||||
|
||||
b) Waiting for events on the device(s)
|
||||
|
||||
while (1) {
|
||||
char buf[4];
|
||||
|
||||
int ret = read(dev_fd, buf, 4); /* will block */
|
||||
|
||||
handle_device_events(dev_fd, map);
|
||||
}
|
||||
|
||||
|
||||
c) Managing the command ring
|
||||
|
||||
#include <linux/target_core_user.h>
|
||||
|
||||
int handle_device_events(int fd, void *map)
|
||||
{
|
||||
struct tcmu_mailbox *mb = map;
|
||||
struct tcmu_cmd_entry *ent = (void *) mb + mb->cmdr_off + mb->cmd_tail;
|
||||
int did_some_work = 0;
|
||||
|
||||
/* Process events from cmd ring until we catch up with cmd_head */
|
||||
while (ent != (void *)mb + mb->cmdr_off + mb->cmd_head) {
|
||||
|
||||
if (tcmu_hdr_get_op(&ent->hdr) == TCMU_OP_CMD) {
|
||||
uint8_t *cdb = (void *)mb + ent->req.cdb_off;
|
||||
bool success = true;
|
||||
|
||||
/* Handle command here. */
|
||||
printf("SCSI opcode: 0x%x\n", cdb[0]);
|
||||
|
||||
/* Set response fields */
|
||||
if (success)
|
||||
ent->rsp.scsi_status = SCSI_NO_SENSE;
|
||||
else {
|
||||
/* Also fill in rsp->sense_buffer here */
|
||||
ent->rsp.scsi_status = SCSI_CHECK_CONDITION;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Do nothing for PAD entries */
|
||||
}
|
||||
|
||||
/* update cmd_tail */
|
||||
mb->cmd_tail = (mb->cmd_tail + tcmu_hdr_get_len(&ent->hdr)) % mb->cmdr_size;
|
||||
ent = (void *) mb + mb->cmdr_off + mb->cmd_tail;
|
||||
did_some_work = 1;
|
||||
}
|
||||
|
||||
/* Notify the kernel that work has been finished */
|
||||
if (did_some_work) {
|
||||
uint32_t buf = 0;
|
||||
|
||||
write(fd, &buf, 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Command filtering and pass_level
|
||||
--------------------------------
|
||||
|
||||
TCMU supports a "pass_level" option with valid values of 0 or 1. When
|
||||
the value is 0 (the default), nearly all SCSI commands received for
|
||||
the device are passed through to the handler. This allows maximum
|
||||
flexibility but increases the amount of code required by the handler,
|
||||
to support all mandatory SCSI commands. If pass_level is set to 1,
|
||||
then only IO-related commands are presented, and the rest are handled
|
||||
by LIO's in-kernel command emulation. The commands presented at level
|
||||
1 include all versions of:
|
||||
|
||||
READ
|
||||
WRITE
|
||||
WRITE_VERIFY
|
||||
XDWRITEREAD
|
||||
WRITE_SAME
|
||||
COMPARE_AND_WRITE
|
||||
SYNCHRONIZE_CACHE
|
||||
UNMAP
|
||||
|
||||
|
||||
A final note
|
||||
------------
|
||||
|
||||
Please be careful to return codes as defined by the SCSI
|
||||
specifications. These are different than some values defined in the
|
||||
scsi/scsi.h include file. For example, CHECK CONDITION's status code
|
||||
is 2, not 1.
|
17
MAINTAINERS
17
MAINTAINERS
@ -5842,6 +5842,14 @@ S: Maintained
|
||||
F: drivers/net/macvlan.c
|
||||
F: include/linux/if_macvlan.h
|
||||
|
||||
MAILBOX API
|
||||
M: Jassi Brar <jassisinghbrar@gmail.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/mailbox/
|
||||
F: include/linux/mailbox_client.h
|
||||
F: include/linux/mailbox_controller.h
|
||||
|
||||
MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
|
||||
M: Michael Kerrisk <mtk.manpages@gmail.com>
|
||||
W: http://www.kernel.org/doc/man-pages
|
||||
@ -6830,7 +6838,7 @@ S: Orphan
|
||||
F: drivers/net/wireless/orinoco/
|
||||
|
||||
OSD LIBRARY and FILESYSTEM
|
||||
M: Boaz Harrosh <bharrosh@panasas.com>
|
||||
M: Boaz Harrosh <ooo@electrozaur.com>
|
||||
M: Benny Halevy <bhalevy@primarydata.com>
|
||||
L: osd-dev@open-osd.org
|
||||
W: http://open-osd.org
|
||||
@ -6840,6 +6848,13 @@ F: drivers/scsi/osd/
|
||||
F: include/scsi/osd_*
|
||||
F: fs/exofs/
|
||||
|
||||
OVERLAYFS FILESYSTEM
|
||||
M: Miklos Szeredi <miklos@szeredi.hu>
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
S: Supported
|
||||
F: fs/overlayfs/*
|
||||
F: Documentation/filesystems/overlayfs.txt
|
||||
|
||||
P54 WIRELESS DRIVER
|
||||
M: Christian Lamparter <chunkeey@googlemail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc2
|
||||
NAME = Shuffling Zombie Juror
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -9,6 +9,7 @@
|
||||
config ARC
|
||||
def_bool y
|
||||
select BUILDTIME_EXTABLE_SORT
|
||||
select COMMON_CLK
|
||||
select CLONE_BACKWARDS
|
||||
# ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
|
||||
select DEVTMPFS if !INITRAMFS_SOURCE=""
|
||||
@ -73,9 +74,6 @@ config STACKTRACE_SUPPORT
|
||||
config HAVE_LATENCYTOP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config NO_DMA
|
||||
def_bool n
|
||||
|
||||
source "init/Kconfig"
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
||||
@ -354,7 +352,7 @@ config ARC_CURR_IN_REG
|
||||
kernel mode. This saves memory access for each such access
|
||||
|
||||
|
||||
config ARC_MISALIGN_ACCESS
|
||||
config ARC_EMUL_UNALIGNED
|
||||
bool "Emulate unaligned memory access (userspace only)"
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
|
@ -25,7 +25,6 @@ ifdef CONFIG_ARC_CURR_IN_REG
|
||||
LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h
|
||||
endif
|
||||
|
||||
upto_gcc42 := $(call cc-ifversion, -le, 0402, y)
|
||||
upto_gcc44 := $(call cc-ifversion, -le, 0404, y)
|
||||
atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y)
|
||||
atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y)
|
||||
@ -60,25 +59,11 @@ ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
|
||||
# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
|
||||
ldflags-$(upto_gcc44) += -marclinux
|
||||
|
||||
ARC_LIBGCC := -mA7
|
||||
cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16
|
||||
|
||||
ifndef CONFIG_ARC_HAS_HW_MPY
|
||||
cflags-y += -mno-mpy
|
||||
|
||||
# newlib for ARC700 assumes MPY to be always present, which is generally true
|
||||
# However, if someone really doesn't want MPY, we need to use the 600 ver
|
||||
# which coupled with -mno-mpy will use mpy emulation
|
||||
# With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments,
|
||||
# e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted
|
||||
|
||||
ifeq ($(upto_gcc42),y)
|
||||
ARC_LIBGCC := -marc600
|
||||
cflags-y += -multcost=30
|
||||
endif
|
||||
endif
|
||||
|
||||
LIBGCC := $(shell $(CC) $(ARC_LIBGCC) $(cflags-y) --print-libgcc-file-name)
|
||||
LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
|
||||
|
||||
# Modules with short calls might break for calls into builtin-kernel
|
||||
KBUILD_CFLAGS_MODULE += -mlong-calls
|
||||
|
@ -24,11 +24,6 @@
|
||||
serial0 = &arcuart0;
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x10000000>; /* 256M */
|
||||
};
|
||||
|
||||
fpga {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
|
@ -20,18 +20,13 @@
|
||||
/* this is for console on PGU */
|
||||
/* bootargs = "console=tty0 consoleblank=0"; */
|
||||
/* this is for console on serial */
|
||||
bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=ttyS0,115200n8 consoleblank=0 debug";
|
||||
bootargs = "earlycon=uart8250,mmio32,0xc0000000,115200n8 console=tty0 console=ttyS0,115200n8 consoleblank=0 debug";
|
||||
};
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x80000000 0x10000000>; /* 256M */
|
||||
};
|
||||
|
||||
fpga {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
|
@ -23,7 +23,6 @@ CONFIG_MODULES=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_PLAT_FPGA_LEGACY=y
|
||||
CONFIG_ARC_BOARD_ML509=y
|
||||
# CONFIG_ARC_HAS_RTSC is not set
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="angel4"
|
||||
CONFIG_PREEMPT=y
|
||||
|
@ -20,7 +20,6 @@ CONFIG_MODULES=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_PLAT_FPGA_LEGACY=y
|
||||
CONFIG_ARC_BOARD_ML509=y
|
||||
# CONFIG_ARC_HAS_RTSC is not set
|
||||
CONFIG_ARC_BUILTIN_DTB_NAME="angel4"
|
||||
CONFIG_PREEMPT=y
|
||||
|
@ -21,7 +21,6 @@ CONFIG_MODULES=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
# CONFIG_IOSCHED_CFQ is not set
|
||||
CONFIG_ARC_PLAT_FPGA_LEGACY=y
|
||||
CONFIG_ARC_BOARD_ML509=y
|
||||
# CONFIG_ARC_IDE is not set
|
||||
# CONFIG_ARCTANGENT_EMAC is not set
|
||||
# CONFIG_ARC_HAS_RTSC is not set
|
||||
|
@ -9,19 +9,16 @@
|
||||
#ifndef _ASM_ARC_ARCREGS_H
|
||||
#define _ASM_ARC_ARCREGS_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Build Configuration Registers */
|
||||
#define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */
|
||||
#define ARC_REG_CRC_BCR 0x62
|
||||
#define ARC_REG_DVFB_BCR 0x64
|
||||
#define ARC_REG_EXTARITH_BCR 0x65
|
||||
#define ARC_REG_VECBASE_BCR 0x68
|
||||
#define ARC_REG_PERIBASE_BCR 0x69
|
||||
#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */
|
||||
#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */
|
||||
#define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */
|
||||
#define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */
|
||||
#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
|
||||
#define ARC_REG_TIMERS_BCR 0x75
|
||||
#define ARC_REG_AP_BCR 0x76
|
||||
#define ARC_REG_ICCM_BCR 0x78
|
||||
#define ARC_REG_XY_MEM_BCR 0x79
|
||||
#define ARC_REG_MAC_BCR 0x7a
|
||||
@ -31,6 +28,9 @@
|
||||
#define ARC_REG_MIXMAX_BCR 0x7e
|
||||
#define ARC_REG_BARREL_BCR 0x7f
|
||||
#define ARC_REG_D_UNCACH_BCR 0x6A
|
||||
#define ARC_REG_BPU_BCR 0xc0
|
||||
#define ARC_REG_ISA_CFG_BCR 0xc1
|
||||
#define ARC_REG_SMART_BCR 0xFF
|
||||
|
||||
/* status32 Bits Positions */
|
||||
#define STATUS_AE_BIT 5 /* Exception active */
|
||||
@ -191,14 +191,6 @@
|
||||
#define PAGES_TO_KB(n_pages) ((n_pages) << (PAGE_SHIFT - 10))
|
||||
#define PAGES_TO_MB(n_pages) (PAGES_TO_KB(n_pages) >> 10)
|
||||
|
||||
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||
/* These DPFP regs need to be saved/restored across ctx-sw */
|
||||
struct arc_fpu {
|
||||
struct {
|
||||
unsigned int l, h;
|
||||
} aux_dpfp[2];
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
***************************************************************
|
||||
@ -212,27 +204,19 @@ struct bcr_identity {
|
||||
#endif
|
||||
};
|
||||
|
||||
#define EXTN_SWAP_VALID 0x1
|
||||
#define EXTN_NORM_VALID 0x2
|
||||
#define EXTN_MINMAX_VALID 0x2
|
||||
#define EXTN_BARREL_VALID 0x2
|
||||
|
||||
struct bcr_extn {
|
||||
struct bcr_isa {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2,
|
||||
norm:2, swap:1;
|
||||
unsigned int pad1:23, atomic1:1, ver:8;
|
||||
#else
|
||||
unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2,
|
||||
crc:1, pad:20;
|
||||
unsigned int ver:8, atomic1:1, pad1:23;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* DSP Options Ref Manual */
|
||||
struct bcr_extn_mac_mul {
|
||||
struct bcr_mpy {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad:16, type:8, ver:8;
|
||||
unsigned int pad:8, x1616:8, dsp:4, cycles:2, type:2, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, type:8, pad:16;
|
||||
unsigned int ver:8, type:2, cycles:2, dsp:4, x1616:8, pad:8;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -251,6 +235,7 @@ struct bcr_perip {
|
||||
unsigned int pad:8, sz:8, pad2:8, start:8;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct bcr_iccm {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int base:16, pad:5, sz:3, ver:8;
|
||||
@ -277,8 +262,8 @@ struct bcr_dccm {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Both SP and DP FPU BCRs have same format */
|
||||
struct bcr_fp {
|
||||
/* ARCompact: Both SP and DP FPU BCRs have same format */
|
||||
struct bcr_fp_arcompact {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int fast:1, ver:8;
|
||||
#else
|
||||
@ -286,6 +271,30 @@ struct bcr_fp {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct bcr_timer {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct bcr_bpu_arcompact {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad2:19, fam:1, pad:2, ent:2, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, ent:2, pad:2, fam:1, pad2:19;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct bcr_generic {
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
unsigned int pad:24, ver:8;
|
||||
#else
|
||||
unsigned int ver:8, pad:24;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
*******************************************************************
|
||||
* Generic structures to hold build configuration used at runtime
|
||||
@ -299,6 +308,10 @@ struct cpuinfo_arc_cache {
|
||||
unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6;
|
||||
};
|
||||
|
||||
struct cpuinfo_arc_bpu {
|
||||
unsigned int ver, full, num_cache, num_pred;
|
||||
};
|
||||
|
||||
struct cpuinfo_arc_ccm {
|
||||
unsigned int base_addr, sz;
|
||||
};
|
||||
@ -306,21 +319,25 @@ struct cpuinfo_arc_ccm {
|
||||
struct cpuinfo_arc {
|
||||
struct cpuinfo_arc_cache icache, dcache;
|
||||
struct cpuinfo_arc_mmu mmu;
|
||||
struct cpuinfo_arc_bpu bpu;
|
||||
struct bcr_identity core;
|
||||
unsigned int timers;
|
||||
struct bcr_isa isa;
|
||||
struct bcr_timer timers;
|
||||
unsigned int vec_base;
|
||||
unsigned int uncached_base;
|
||||
struct cpuinfo_arc_ccm iccm, dccm;
|
||||
struct bcr_extn extn;
|
||||
struct {
|
||||
unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3,
|
||||
fpu_sp:1, fpu_dp:1, pad2:6,
|
||||
debug:1, ap:1, smart:1, rtt:1, pad3:4,
|
||||
pad4:8;
|
||||
} extn;
|
||||
struct bcr_mpy extn_mpy;
|
||||
struct bcr_extn_xymem extn_xymem;
|
||||
struct bcr_extn_mac_mul extn_mac_mul;
|
||||
struct bcr_fp fp, dpfp;
|
||||
};
|
||||
|
||||
extern struct cpuinfo_arc cpuinfo_arc700[];
|
||||
|
||||
#endif /* __ASEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_ARC_ARCREGS_H */
|
||||
|
@ -9,8 +9,6 @@
|
||||
#ifndef _ASM_ARC_ATOMIC_H
|
||||
#define _ASM_ARC_ATOMIC_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
@ -170,5 +168,3 @@ ATOMIC_OP(and, &=, and)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -13,8 +13,6 @@
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
@ -508,6 +506,4 @@ static inline __attribute__ ((const)) int __ffs(unsigned long word)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
@ -21,10 +21,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
|
||||
unsigned long address);
|
||||
void die(const char *str, struct pt_regs *regs, unsigned long address);
|
||||
|
||||
#define BUG() do { \
|
||||
dump_stack(); \
|
||||
pr_warn("Kernel BUG in %s: %s: %d!\n", \
|
||||
__FILE__, __func__, __LINE__); \
|
||||
#define BUG() do { \
|
||||
pr_warn("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
|
||||
dump_stack(); \
|
||||
} while (0)
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define CACHE_LINE_MASK (~(L1_CACHE_BYTES - 1))
|
||||
|
||||
/*
|
||||
* ARC700 doesn't cache any access in top 256M.
|
||||
* ARC700 doesn't cache any access in top 1G (0xc000_0000 to 0xFFFF_FFFF)
|
||||
* Ideal for wiring memory mapped peripherals as we don't need to do
|
||||
* explicit uncached accesses (LD.di/ST.di) hence more portable drivers
|
||||
*/
|
||||
|
@ -12,8 +12,6 @@
|
||||
#ifndef _ASM_ARC_CURRENT_H
|
||||
#define _ASM_ARC_CURRENT_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_ARC_CURR_IN_REG
|
||||
@ -27,6 +25,4 @@ register struct task_struct *curr_arc asm("r25");
|
||||
|
||||
#endif /* ! __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_ARC_CURRENT_H */
|
||||
|
@ -15,8 +15,6 @@
|
||||
* -Conditionally disable interrupts (if they are not enabled, don't disable)
|
||||
*/
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/arcregs.h>
|
||||
|
||||
/* status32 Reg bits related to Interrupt Handling */
|
||||
@ -169,6 +167,4 @@ static inline int arch_irqs_disabled(void)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
* register API yet */
|
||||
#undef DBG_MAX_REG_NUM
|
||||
|
||||
#define GDB_MAX_REGS 39
|
||||
#define GDB_MAX_REGS 87
|
||||
|
||||
#define BREAK_INSTR_SIZE 2
|
||||
#define CACHE_FLUSH_IS_SAFE 1
|
||||
@ -33,23 +33,27 @@ static inline void arch_kgdb_breakpoint(void)
|
||||
|
||||
extern void kgdb_trap(struct pt_regs *regs);
|
||||
|
||||
enum arc700_linux_regnums {
|
||||
/* This is the numbering of registers according to the GDB. See GDB's
|
||||
* arc-tdep.h for details.
|
||||
*
|
||||
* Registers are ordered for GDB 7.5. It is incompatible with GDB 6.8. */
|
||||
enum arc_linux_regnums {
|
||||
_R0 = 0,
|
||||
_R1, _R2, _R3, _R4, _R5, _R6, _R7, _R8, _R9, _R10, _R11, _R12, _R13,
|
||||
_R14, _R15, _R16, _R17, _R18, _R19, _R20, _R21, _R22, _R23, _R24,
|
||||
_R25, _R26,
|
||||
_BTA = 27,
|
||||
_LP_START = 28,
|
||||
_LP_END = 29,
|
||||
_LP_COUNT = 30,
|
||||
_STATUS32 = 31,
|
||||
_BLINK = 32,
|
||||
_FP = 33,
|
||||
__SP = 34,
|
||||
_EFA = 35,
|
||||
_RET = 36,
|
||||
_ORIG_R8 = 37,
|
||||
_STOP_PC = 38
|
||||
_FP = 27,
|
||||
__SP = 28,
|
||||
_R30 = 30,
|
||||
_BLINK = 31,
|
||||
_LP_COUNT = 60,
|
||||
_STOP_PC = 64,
|
||||
_RET = 64,
|
||||
_LP_START = 65,
|
||||
_LP_END = 66,
|
||||
_STATUS32 = 67,
|
||||
_ECR = 76,
|
||||
_BTA = 82,
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -14,12 +14,19 @@
|
||||
#ifndef __ASM_ARC_PROCESSOR_H
|
||||
#define __ASM_ARC_PROCESSOR_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||
/* These DPFP regs need to be saved/restored across ctx-sw */
|
||||
struct arc_fpu {
|
||||
struct {
|
||||
unsigned int l, h;
|
||||
} aux_dpfp[2];
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Arch specific stuff which needs to be saved per task.
|
||||
* However these items are not so important so as to earn a place in
|
||||
* struct thread_info
|
||||
@ -128,6 +135,4 @@ extern unsigned int get_wchan(struct task_struct *p);
|
||||
*/
|
||||
#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ASM_ARC_PROCESSOR_H */
|
||||
|
@ -29,7 +29,6 @@ struct cpuinfo_data {
|
||||
};
|
||||
|
||||
extern int root_mountflags, end_mem;
|
||||
extern int running_on_hw;
|
||||
|
||||
void setup_processor(void);
|
||||
void __init setup_arch_memory(void);
|
||||
|
@ -59,7 +59,15 @@ struct plat_smp_ops {
|
||||
/* TBD: stop exporting it for direct population by platform */
|
||||
extern struct plat_smp_ops plat_smp_ops;
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
#else /* CONFIG_SMP */
|
||||
|
||||
static inline void smp_init_cpus(void) {}
|
||||
static inline const char *arc_platform_smp_cpuinfo(void)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_SMP */
|
||||
|
||||
/*
|
||||
* ARC700 doesn't support atomic Read-Modify-Write ops.
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
#define __HAVE_ARCH_MEMCMP
|
||||
@ -36,5 +34,4 @@ extern char *strcpy(char *dest, const char *src);
|
||||
extern int strcmp(const char *cs, const char *ct);
|
||||
extern __kernel_size_t strlen(const char *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_ARC_STRING_H */
|
||||
|
@ -9,8 +9,6 @@
|
||||
#ifndef _ASM_ARC_SYSCALLS_H
|
||||
#define _ASM_ARC_SYSCALLS_H 1
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/types.h>
|
||||
@ -22,6 +20,4 @@ int sys_arc_gettls(void);
|
||||
|
||||
#include <asm-generic/syscalls.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
@ -16,8 +16,6 @@
|
||||
#ifndef _ASM_THREAD_INFO_H
|
||||
#define _ASM_THREAD_INFO_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifdef CONFIG_16KSTACKS
|
||||
@ -114,6 +112,4 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
|
||||
* syscall, so all that reamins to be tested is _TIF_WORK_MASK
|
||||
*/
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_THREAD_INFO_H */
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <asm-generic/unaligned.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
#ifdef CONFIG_ARC_MISALIGN_ACCESS
|
||||
#ifdef CONFIG_ARC_EMUL_UNALIGNED
|
||||
int misaligned_fixup(unsigned long address, struct pt_regs *regs,
|
||||
struct callee_regs *cregs);
|
||||
#else
|
||||
|
@ -16,7 +16,7 @@ obj-$(CONFIG_MODULES) += arcksyms.o module.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_ARC_DW2_UNWIND) += unwind.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o
|
||||
obj-$(CONFIG_ARC_EMUL_UNALIGNED) += unaligned.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/disasm.h>
|
||||
|
||||
#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \
|
||||
#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_EMUL_UNALIGNED) || \
|
||||
defined(CONFIG_KPROBES)
|
||||
|
||||
/* disasm_instr: Analyses instruction at addr, stores
|
||||
@ -535,4 +535,4 @@ int __kprobes disasm_next_pc(unsigned long pc, struct pt_regs *regs,
|
||||
return instr.is_branch;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_KGDB || CONFIG_ARC_MISALIGN_ACCESS || CONFIG_KPROBES */
|
||||
#endif /* CONFIG_KGDB || CONFIG_ARC_EMUL_UNALIGNED || CONFIG_KPROBES */
|
||||
|
@ -91,16 +91,6 @@ stext:
|
||||
st r0, [@uboot_tag]
|
||||
st r2, [@uboot_arg]
|
||||
|
||||
; Identify if running on ISS vs Silicon
|
||||
; IDENTITY Reg [ 3 2 1 0 ]
|
||||
; (chip-id) ^^^^^ ==> 0xffff for ISS
|
||||
lr r0, [identity]
|
||||
lsr r3, r0, 16
|
||||
cmp r3, 0xffff
|
||||
mov.z r4, 0
|
||||
mov.nz r4, 1
|
||||
st r4, [@running_on_hw]
|
||||
|
||||
; setup "current" tsk and optionally cache it in dedicated r25
|
||||
mov r9, @init_task
|
||||
SET_CURR_TASK_ON_CPU r9, r0 ; r9 = tsk, r0 = scratch
|
||||
|
@ -158,11 +158,6 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs)
|
||||
{
|
||||
return instruction_pointer(regs);
|
||||
}
|
||||
|
||||
int kgdb_arch_init(void)
|
||||
{
|
||||
single_step_data.armed = 0;
|
||||
|
@ -244,25 +244,23 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
|
||||
pr_err("This core does not have performance counters!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS);
|
||||
|
||||
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu),
|
||||
GFP_KERNEL);
|
||||
READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
|
||||
if (!cc_bcr.v) {
|
||||
pr_err("Performance counters exist, but no countable conditions?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL);
|
||||
if (!arc_pmu)
|
||||
return -ENOMEM;
|
||||
|
||||
arc_pmu->n_counters = pct_bcr.c;
|
||||
BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS);
|
||||
|
||||
arc_pmu->counter_size = 32 + (pct_bcr.s << 4);
|
||||
pr_info("ARC PMU found with %d counters of size %d bits\n",
|
||||
arc_pmu->n_counters, arc_pmu->counter_size);
|
||||
|
||||
READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
|
||||
|
||||
if (!cc_bcr.v)
|
||||
pr_err("Strange! Performance counters exist, but no countable conditions?\n");
|
||||
|
||||
pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c);
|
||||
pr_info("ARC perf\t: %d counters (%d bits), %d countable conditions\n",
|
||||
arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c);
|
||||
|
||||
cc_name.str[8] = 0;
|
||||
for (i = 0; i < PERF_COUNT_HW_MAX; i++)
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include <linux/console.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/cache.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/arcregs.h>
|
||||
@ -24,11 +26,10 @@
|
||||
#include <asm/unwind.h>
|
||||
#include <asm/clk.h>
|
||||
#include <asm/mach_desc.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x))
|
||||
|
||||
int running_on_hw = 1; /* vs. on ISS */
|
||||
|
||||
/* Part of U-boot ABI: see head.S */
|
||||
int __initdata uboot_tag;
|
||||
char __initdata *uboot_arg;
|
||||
@ -42,26 +43,26 @@ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
|
||||
static void read_arc_build_cfg_regs(void)
|
||||
{
|
||||
struct bcr_perip uncached_space;
|
||||
struct bcr_generic bcr;
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||
FIX_PTR(cpu);
|
||||
|
||||
READ_BCR(AUX_IDENTITY, cpu->core);
|
||||
READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa);
|
||||
|
||||
cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR);
|
||||
READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers);
|
||||
cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
|
||||
|
||||
READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
|
||||
cpu->uncached_base = uncached_space.start << 24;
|
||||
|
||||
cpu->extn.mul = read_aux_reg(ARC_REG_MUL_BCR);
|
||||
cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR);
|
||||
cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR);
|
||||
cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR);
|
||||
cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR);
|
||||
READ_BCR(ARC_REG_MAC_BCR, cpu->extn_mac_mul);
|
||||
READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy);
|
||||
|
||||
cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR);
|
||||
cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR);
|
||||
cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */
|
||||
cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR) > 1 ? 1 : 0; /* 2,3 */
|
||||
cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0; /* 1,3 */
|
||||
cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0;
|
||||
cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */
|
||||
|
||||
/* Note that we read the CCM BCRs independent of kernel config
|
||||
* This is to catch the cases where user doesn't know that
|
||||
@ -95,43 +96,76 @@ static void read_arc_build_cfg_regs(void)
|
||||
read_decode_mmu_bcr();
|
||||
read_decode_cache_bcr();
|
||||
|
||||
READ_BCR(ARC_REG_FP_BCR, cpu->fp);
|
||||
READ_BCR(ARC_REG_DPFP_BCR, cpu->dpfp);
|
||||
{
|
||||
struct bcr_fp_arcompact sp, dp;
|
||||
struct bcr_bpu_arcompact bpu;
|
||||
|
||||
READ_BCR(ARC_REG_FP_BCR, sp);
|
||||
READ_BCR(ARC_REG_DPFP_BCR, dp);
|
||||
cpu->extn.fpu_sp = sp.ver ? 1 : 0;
|
||||
cpu->extn.fpu_dp = dp.ver ? 1 : 0;
|
||||
|
||||
READ_BCR(ARC_REG_BPU_BCR, bpu);
|
||||
cpu->bpu.ver = bpu.ver;
|
||||
cpu->bpu.full = bpu.fam ? 1 : 0;
|
||||
if (bpu.ent) {
|
||||
cpu->bpu.num_cache = 256 << (bpu.ent - 1);
|
||||
cpu->bpu.num_pred = 256 << (bpu.ent - 1);
|
||||
}
|
||||
}
|
||||
|
||||
READ_BCR(ARC_REG_AP_BCR, bcr);
|
||||
cpu->extn.ap = bcr.ver ? 1 : 0;
|
||||
|
||||
READ_BCR(ARC_REG_SMART_BCR, bcr);
|
||||
cpu->extn.smart = bcr.ver ? 1 : 0;
|
||||
|
||||
cpu->extn.debug = cpu->extn.ap | cpu->extn.smart;
|
||||
}
|
||||
|
||||
static const struct cpuinfo_data arc_cpu_tbl[] = {
|
||||
{ {0x10, "ARCTangent A5"}, 0x1F},
|
||||
{ {0x20, "ARC 600" }, 0x2F},
|
||||
{ {0x30, "ARC 700" }, 0x33},
|
||||
{ {0x34, "ARC 700 R4.10"}, 0x34},
|
||||
{ {0x35, "ARC 700 R4.11"}, 0x35},
|
||||
{ {0x00, NULL } }
|
||||
};
|
||||
|
||||
#define IS_AVAIL1(v, str) ((v) ? str : "")
|
||||
#define IS_USED(cfg) (IS_ENABLED(cfg) ? "" : "(not used) ")
|
||||
#define IS_AVAIL2(v, str, cfg) IS_AVAIL1(v, str), IS_AVAIL1(v, IS_USED(cfg))
|
||||
|
||||
static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
|
||||
{
|
||||
int n = 0;
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
|
||||
struct bcr_identity *core = &cpu->core;
|
||||
const struct cpuinfo_data *tbl;
|
||||
int be = 0;
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
be = 1;
|
||||
#endif
|
||||
char *isa_nm;
|
||||
int i, be, atomic;
|
||||
int n = 0;
|
||||
|
||||
FIX_PTR(cpu);
|
||||
|
||||
{
|
||||
isa_nm = "ARCompact";
|
||||
be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
|
||||
|
||||
atomic = cpu->isa.atomic1;
|
||||
if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */
|
||||
atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC);
|
||||
}
|
||||
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"\nARC IDENTITY\t: Family [%#02x]"
|
||||
" Cpu-id [%#02x] Chip-id [%#4x]\n",
|
||||
core->family, core->cpu_id,
|
||||
core->chip_id);
|
||||
"\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n",
|
||||
core->family, core->cpu_id, core->chip_id);
|
||||
|
||||
for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) {
|
||||
if ((core->family >= tbl->info.id) &&
|
||||
(core->family <= tbl->up_range)) {
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"processor\t: %s %s\n",
|
||||
tbl->info.str,
|
||||
be ? "[Big Endian]" : "");
|
||||
"processor [%d]\t: %s (%s ISA) %s\n",
|
||||
cpu_id, tbl->info.str, isa_nm,
|
||||
IS_AVAIL1(be, "[Big-Endian]"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -143,102 +177,82 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
|
||||
(unsigned int)(arc_get_core_freq() / 1000000),
|
||||
(unsigned int)(arc_get_core_freq() / 10000) % 100);
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Timers\t\t: %s %s\n",
|
||||
(cpu->timers & 0x200) ? "TIMER1" : "",
|
||||
(cpu->timers & 0x100) ? "TIMER0" : "");
|
||||
n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
|
||||
IS_AVAIL1(cpu->timers.t0, "Timer0 "),
|
||||
IS_AVAIL1(cpu->timers.t1, "Timer1 "),
|
||||
IS_AVAIL2(cpu->timers.rtsc, "64-bit RTSC ", CONFIG_ARC_HAS_RTSC));
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Vect Tbl Base\t: %#x\n",
|
||||
cpu->vec_base);
|
||||
n += i = scnprintf(buf + n, len - n, "%s%s",
|
||||
IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC));
|
||||
|
||||
n += scnprintf(buf + n, len - n, "UNCACHED Base\t: %#x\n",
|
||||
cpu->uncached_base);
|
||||
if (i)
|
||||
n += scnprintf(buf + n, len - n, "\n\t\t: ");
|
||||
|
||||
n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n",
|
||||
IS_AVAIL1(cpu->extn_mpy.ver, "mpy "),
|
||||
IS_AVAIL1(cpu->extn.norm, "norm "),
|
||||
IS_AVAIL1(cpu->extn.barrel, "barrel-shift "),
|
||||
IS_AVAIL1(cpu->extn.swap, "swap "),
|
||||
IS_AVAIL1(cpu->extn.minmax, "minmax "),
|
||||
IS_AVAIL1(cpu->extn.crc, "crc "),
|
||||
IS_AVAIL2(1, "swape", CONFIG_ARC_HAS_SWAPE));
|
||||
|
||||
if (cpu->bpu.ver)
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n",
|
||||
IS_AVAIL1(cpu->bpu.full, "full"),
|
||||
IS_AVAIL1(!cpu->bpu.full, "partial"),
|
||||
cpu->bpu.num_cache, cpu->bpu.num_pred);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const struct id_to_str mul_type_nm[] = {
|
||||
{ 0x0, "N/A"},
|
||||
{ 0x1, "32x32 (spl Result Reg)" },
|
||||
{ 0x2, "32x32 (ANY Result Reg)" }
|
||||
};
|
||||
|
||||
static const struct id_to_str mac_mul_nm[] = {
|
||||
{0x0, "N/A"},
|
||||
{0x1, "N/A"},
|
||||
{0x2, "Dual 16 x 16"},
|
||||
{0x3, "N/A"},
|
||||
{0x4, "32x16"},
|
||||
{0x5, "N/A"},
|
||||
{0x6, "Dual 16x16 and 32x16"}
|
||||
};
|
||||
|
||||
static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
|
||||
{
|
||||
int n = 0;
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id];
|
||||
|
||||
FIX_PTR(cpu);
|
||||
#define IS_AVAIL1(var, str) ((var) ? str : "")
|
||||
#define IS_AVAIL2(var, str) ((var == 0x2) ? str : "")
|
||||
#define IS_USED(cfg) (IS_ENABLED(cfg) ? "(in-use)" : "(not used)")
|
||||
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"Extn [700-Base]\t: %s %s %s %s %s %s\n",
|
||||
IS_AVAIL2(cpu->extn.norm, "norm,"),
|
||||
IS_AVAIL2(cpu->extn.barrel, "barrel-shift,"),
|
||||
IS_AVAIL1(cpu->extn.swap, "swap,"),
|
||||
IS_AVAIL2(cpu->extn.minmax, "minmax,"),
|
||||
IS_AVAIL1(cpu->extn.crc, "crc,"),
|
||||
IS_AVAIL2(cpu->extn.ext_arith, "ext-arith"));
|
||||
"Vector Table\t: %#x\nUncached Base\t: %#x\n",
|
||||
cpu->vec_base, cpu->uncached_base);
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Extn [700-MPY]\t: %s",
|
||||
mul_type_nm[cpu->extn.mul].str);
|
||||
if (cpu->extn.fpu_sp || cpu->extn.fpu_dp)
|
||||
n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n",
|
||||
IS_AVAIL1(cpu->extn.fpu_sp, "SP "),
|
||||
IS_AVAIL1(cpu->extn.fpu_dp, "DP "));
|
||||
|
||||
n += scnprintf(buf + n, len - n, " MAC MPY: %s\n",
|
||||
mac_mul_nm[cpu->extn_mac_mul.type].str);
|
||||
if (cpu->extn.debug)
|
||||
n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n",
|
||||
IS_AVAIL1(cpu->extn.ap, "ActionPoint "),
|
||||
IS_AVAIL1(cpu->extn.smart, "smaRT "),
|
||||
IS_AVAIL1(cpu->extn.rtt, "RTT "));
|
||||
|
||||
if (cpu->core.family == 0x34) {
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n",
|
||||
IS_USED(CONFIG_ARC_HAS_LLSC),
|
||||
IS_USED(CONFIG_ARC_HAS_SWAPE),
|
||||
IS_USED(CONFIG_ARC_HAS_RTSC));
|
||||
}
|
||||
|
||||
n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s",
|
||||
!(cpu->dccm.sz || cpu->iccm.sz) ? "N/A" : "");
|
||||
|
||||
if (cpu->dccm.sz)
|
||||
n += scnprintf(buf + n, len - n, "DCCM: @ %x, %d KB ",
|
||||
cpu->dccm.base_addr, TO_KB(cpu->dccm.sz));
|
||||
|
||||
if (cpu->iccm.sz)
|
||||
n += scnprintf(buf + n, len - n, "ICCM: @ %x, %d KB",
|
||||
if (cpu->dccm.sz || cpu->iccm.sz)
|
||||
n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n",
|
||||
cpu->dccm.base_addr, TO_KB(cpu->dccm.sz),
|
||||
cpu->iccm.base_addr, TO_KB(cpu->iccm.sz));
|
||||
|
||||
n += scnprintf(buf + n, len - n, "\nExtn [FPU]\t: %s",
|
||||
!(cpu->fp.ver || cpu->dpfp.ver) ? "N/A" : "");
|
||||
|
||||
if (cpu->fp.ver)
|
||||
n += scnprintf(buf + n, len - n, "SP [v%d] %s",
|
||||
cpu->fp.ver, cpu->fp.fast ? "(fast)" : "");
|
||||
|
||||
if (cpu->dpfp.ver)
|
||||
n += scnprintf(buf + n, len - n, "DP [v%d] %s",
|
||||
cpu->dpfp.ver, cpu->dpfp.fast ? "(fast)" : "");
|
||||
|
||||
n += scnprintf(buf + n, len - n, "\n");
|
||||
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"OS ABI [v3]\t: no-legacy-syscalls\n");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void arc_chk_ccms(void)
|
||||
static void arc_chk_core_config(void)
|
||||
{
|
||||
#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||
int fpu_enabled;
|
||||
|
||||
if (!cpu->timers.t0)
|
||||
panic("Timer0 is not present!\n");
|
||||
|
||||
if (!cpu->timers.t1)
|
||||
panic("Timer1 is not present!\n");
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARC_HAS_RTSC) && !cpu->timers.rtsc)
|
||||
panic("RTSC is not present\n");
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_DCCM
|
||||
/*
|
||||
@ -256,33 +270,20 @@ static void arc_chk_ccms(void)
|
||||
if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
|
||||
panic("Linux built with incorrect ICCM Size\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that FP hardware and kernel config match
|
||||
* -If hardware contains DPFP, kernel needs to save/restore FPU state
|
||||
* across context switches
|
||||
* -If hardware lacks DPFP, but kernel configured to save FPU state then
|
||||
* kernel trying to access non-existant DPFP regs will crash
|
||||
*
|
||||
* We only check for Dbl precision Floating Point, because only DPFP
|
||||
* hardware has dedicated regs which need to be saved/restored on ctx-sw
|
||||
* (Single Precision uses core regs), thus kernel is kind of oblivious to it
|
||||
*/
|
||||
static void arc_chk_fpu(void)
|
||||
{
|
||||
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
|
||||
/*
|
||||
* FP hardware/software config sanity
|
||||
* -If hardware contains DPFP, kernel needs to save/restore FPU state
|
||||
* -If not, it will crash trying to save/restore the non-existant regs
|
||||
*
|
||||
* (only DPDP checked since SP has no arch visible regs)
|
||||
*/
|
||||
fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE);
|
||||
|
||||
if (cpu->dpfp.ver) {
|
||||
#ifndef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||
pr_warn("DPFP support broken in this kernel...\n");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
|
||||
panic("H/w lacks DPFP support, apps won't work\n");
|
||||
#endif
|
||||
}
|
||||
if (cpu->extn.fpu_dp && !fpu_enabled)
|
||||
pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
|
||||
else if (!cpu->extn.fpu_dp && fpu_enabled)
|
||||
panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -303,15 +304,11 @@ void setup_processor(void)
|
||||
|
||||
arc_mmu_init();
|
||||
arc_cache_init();
|
||||
arc_chk_ccms();
|
||||
|
||||
printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str)));
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
printk(arc_platform_smp_cpuinfo());
|
||||
#endif
|
||||
|
||||
arc_chk_fpu();
|
||||
arc_chk_core_config();
|
||||
}
|
||||
|
||||
static inline int is_kernel(unsigned long addr)
|
||||
@ -360,11 +357,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
machine_desc->init_early();
|
||||
|
||||
setup_processor();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
smp_init_cpus();
|
||||
#endif
|
||||
|
||||
setup_arch_memory();
|
||||
|
||||
/* copy flat DT out of .init and then unflatten it */
|
||||
@ -385,7 +378,13 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
static int __init customize_machine(void)
|
||||
{
|
||||
/* Add platform devices */
|
||||
of_clk_init(NULL);
|
||||
/*
|
||||
* Traverses flattened DeviceTree - registering platform devices
|
||||
* (if any) complete with their resources
|
||||
*/
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
if (machine_desc->init_machine)
|
||||
machine_desc->init_machine();
|
||||
|
||||
@ -419,19 +418,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
|
||||
seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE));
|
||||
|
||||
seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n",
|
||||
seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n",
|
||||
loops_per_jiffy / (500000 / HZ),
|
||||
(loops_per_jiffy / (5000 / HZ)) % 100);
|
||||
|
||||
seq_printf(m, arc_mmu_mumbojumbo(cpu_id, str, PAGE_SIZE));
|
||||
|
||||
seq_printf(m, arc_cache_mumbojumbo(cpu_id, str, PAGE_SIZE));
|
||||
|
||||
seq_printf(m, arc_extn_mumbojumbo(cpu_id, str, PAGE_SIZE));
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
seq_printf(m, arc_platform_smp_cpuinfo());
|
||||
#endif
|
||||
|
||||
free_page((unsigned long)str);
|
||||
done:
|
||||
|
@ -101,7 +101,7 @@ void __weak arc_platform_smp_wait_to_boot(int cpu)
|
||||
|
||||
const char *arc_platform_smp_cpuinfo(void)
|
||||
{
|
||||
return plat_smp_ops.info;
|
||||
return plat_smp_ops.info ? : "";
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -530,16 +530,9 @@ EXPORT_SYMBOL(dma_cache_wback);
|
||||
*/
|
||||
void flush_icache_range(unsigned long kstart, unsigned long kend)
|
||||
{
|
||||
unsigned int tot_sz, off, sz;
|
||||
unsigned long phy, pfn;
|
||||
unsigned int tot_sz;
|
||||
|
||||
/* printk("Kernel Cache Cohenercy: %lx to %lx\n",kstart, kend); */
|
||||
|
||||
/* This is not the right API for user virtual address */
|
||||
if (kstart < TASK_SIZE) {
|
||||
BUG_ON("Flush icache range for user virtual addr space");
|
||||
return;
|
||||
}
|
||||
WARN(kstart < TASK_SIZE, "%s() can't handle user vaddr", __func__);
|
||||
|
||||
/* Shortcut for bigger flush ranges.
|
||||
* Here we don't care if this was kernel virtual or phy addr
|
||||
@ -572,6 +565,9 @@ void flush_icache_range(unsigned long kstart, unsigned long kend)
|
||||
* straddles across 2 virtual pages and hence need for loop
|
||||
*/
|
||||
while (tot_sz > 0) {
|
||||
unsigned int off, sz;
|
||||
unsigned long phy, pfn;
|
||||
|
||||
off = kstart % PAGE_SIZE;
|
||||
pfn = vmalloc_to_pfn((void *)kstart);
|
||||
phy = (pfn << PAGE_SHIFT) + off;
|
||||
|
@ -609,14 +609,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
|
||||
int n = 0;
|
||||
struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu;
|
||||
|
||||
n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ",
|
||||
p_mmu->ver, TO_KB(p_mmu->pg_sz));
|
||||
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n",
|
||||
"MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n",
|
||||
p_mmu->ver, TO_KB(p_mmu->pg_sz),
|
||||
p_mmu->num_tlb, p_mmu->sets, p_mmu->ways,
|
||||
p_mmu->u_dtlb, p_mmu->u_itlb,
|
||||
IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : "");
|
||||
IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : "");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
menuconfig ARC_PLAT_FPGA_LEGACY
|
||||
bool "\"Legacy\" ARC FPGA dev Boards"
|
||||
select ISS_SMP_EXTN if SMP
|
||||
select ARC_HAS_COH_CACHES if SMP
|
||||
help
|
||||
Support for ARC development boards, provided by Synopsys.
|
||||
These are based on FPGA or ISS. e.g.
|
||||
@ -18,17 +18,6 @@ menuconfig ARC_PLAT_FPGA_LEGACY
|
||||
|
||||
if ARC_PLAT_FPGA_LEGACY
|
||||
|
||||
config ARC_BOARD_ANGEL4
|
||||
bool "ARC Angel4"
|
||||
default y
|
||||
help
|
||||
ARC Angel4 FPGA Ref Platform (Xilinx Virtex Based)
|
||||
|
||||
config ARC_BOARD_ML509
|
||||
bool "ML509"
|
||||
help
|
||||
ARC ML509 FPGA Ref Platform (Xilinx Virtex-5 Based)
|
||||
|
||||
config ISS_SMP_EXTN
|
||||
bool "ARC SMP Extensions (ISS Models only)"
|
||||
default n
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* vineetg: Feb 2009
|
||||
* -For AA4 board, IRQ assignments to peripherals
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_IRQ_H
|
||||
#define __PLAT_IRQ_H
|
||||
|
||||
#define UART0_IRQ 5
|
||||
#define UART1_IRQ 10
|
||||
#define UART2_IRQ 11
|
||||
|
||||
#define IDE_IRQ 13
|
||||
#define PCI_IRQ 14
|
||||
#define PS2_IRQ 15
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define IDU_INTERRUPT_0 16
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* vineetg: Feb 2009
|
||||
* -For AA4 board, System Memory Map for Peripherals etc
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MEMMAP_H
|
||||
#define __PLAT_MEMMAP_H
|
||||
|
||||
#define UART0_BASE 0xC0FC1000
|
||||
#define UART1_BASE 0xC0FC1100
|
||||
|
||||
#define IDE_CONTROLLER_BASE 0xC0FC9000
|
||||
|
||||
#define AHB_PCI_HOST_BRG_BASE 0xC0FD0000
|
||||
|
||||
#define PGU_BASEADDR 0xC0FC8000
|
||||
#define VLCK_ADDR 0xC0FCF028
|
||||
|
||||
#define BVCI_LAT_UNIT_BASE 0xC0FED000
|
||||
|
||||
#define PS2_BASE_ADDR 0xC0FCC000
|
||||
|
||||
#endif
|
@ -8,37 +8,9 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/clk.h>
|
||||
#include <asm/mach_desc.h>
|
||||
#include <plat/memmap.h>
|
||||
#include <plat/smp.h>
|
||||
#include <plat/irq.h>
|
||||
|
||||
static void __init plat_fpga_early_init(void)
|
||||
{
|
||||
pr_info("[plat-arcfpga]: registering early dev resources\n");
|
||||
|
||||
#ifdef CONFIG_ISS_SMP_EXTN
|
||||
iss_model_init_early_smp();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init plat_fpga_populate_dev(void)
|
||||
{
|
||||
/*
|
||||
* Traverses flattened DeviceTree - registering platform devices
|
||||
* (if any) complete with their resources
|
||||
*/
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
/*----------------------- Machine Descriptions ------------------------------
|
||||
*
|
||||
@ -48,41 +20,26 @@ static void __init plat_fpga_populate_dev(void)
|
||||
* callback set, by matching the DT compatible name.
|
||||
*/
|
||||
|
||||
static const char *aa4_compat[] __initconst = {
|
||||
static const char *legacy_fpga_compat[] __initconst = {
|
||||
"snps,arc-angel4",
|
||||
NULL,
|
||||
};
|
||||
|
||||
MACHINE_START(ANGEL4, "angel4")
|
||||
.dt_compat = aa4_compat,
|
||||
.init_early = plat_fpga_early_init,
|
||||
.init_machine = plat_fpga_populate_dev,
|
||||
#ifdef CONFIG_ISS_SMP_EXTN
|
||||
.init_smp = iss_model_init_smp,
|
||||
#endif
|
||||
MACHINE_END
|
||||
|
||||
static const char *ml509_compat[] __initconst = {
|
||||
"snps,arc-ml509",
|
||||
NULL,
|
||||
};
|
||||
|
||||
MACHINE_START(ML509, "ml509")
|
||||
.dt_compat = ml509_compat,
|
||||
.init_early = plat_fpga_early_init,
|
||||
.init_machine = plat_fpga_populate_dev,
|
||||
#ifdef CONFIG_SMP
|
||||
MACHINE_START(LEGACY_FPGA, "legacy_fpga")
|
||||
.dt_compat = legacy_fpga_compat,
|
||||
#ifdef CONFIG_ISS_SMP_EXTN
|
||||
.init_early = iss_model_init_early_smp,
|
||||
.init_smp = iss_model_init_smp,
|
||||
#endif
|
||||
MACHINE_END
|
||||
|
||||
static const char *nsimosci_compat[] __initconst = {
|
||||
static const char *simulation_compat[] __initconst = {
|
||||
"snps,nsim",
|
||||
"snps,nsimosci",
|
||||
NULL,
|
||||
};
|
||||
|
||||
MACHINE_START(NSIMOSCI, "nsimosci")
|
||||
.dt_compat = nsimosci_compat,
|
||||
.init_early = NULL,
|
||||
.init_machine = plat_fpga_populate_dev,
|
||||
MACHINE_START(SIMULATION, "simulation")
|
||||
.dt_compat = simulation_compat,
|
||||
MACHINE_END
|
||||
|
@ -13,9 +13,10 @@
|
||||
|
||||
#include <linux/smp.h>
|
||||
#include <linux/irq.h>
|
||||
#include <plat/irq.h>
|
||||
#include <plat/smp.h>
|
||||
|
||||
#define IDU_INTERRUPT_0 16
|
||||
|
||||
static char smp_cpuinfo_buf[128];
|
||||
|
||||
/*
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
menuconfig ARC_PLAT_TB10X
|
||||
bool "Abilis TB10x"
|
||||
select COMMON_CLK
|
||||
select PINCTRL
|
||||
select PINCTRL_TB10X
|
||||
select PINMUX
|
||||
|
@ -19,21 +19,9 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <asm/mach_desc.h>
|
||||
|
||||
|
||||
static void __init tb10x_platform_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static const char *tb10x_compat[] __initdata = {
|
||||
"abilis,arc-tb10x",
|
||||
NULL,
|
||||
@ -41,5 +29,4 @@ static const char *tb10x_compat[] __initdata = {
|
||||
|
||||
MACHINE_START(TB10x, "tb10x")
|
||||
.dt_compat = tb10x_compat,
|
||||
.init_machine = tb10x_platform_init,
|
||||
MACHINE_END
|
||||
|
@ -262,6 +262,7 @@ CONFIG_WATCHDOG=y
|
||||
CONFIG_XILINX_WATCHDOG=y
|
||||
CONFIG_ORION_WATCHDOG=y
|
||||
CONFIG_SUNXI_WATCHDOG=y
|
||||
CONFIG_MESON_WATCHDOG=y
|
||||
CONFIG_MFD_AS3722=y
|
||||
CONFIG_MFD_BCM590XX=y
|
||||
CONFIG_MFD_CROS_EC=y
|
||||
|
@ -86,7 +86,6 @@ CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
# CONFIG_INET_LRO is not set
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_CAN=m
|
||||
CONFIG_CAN_C_CAN=m
|
||||
@ -112,6 +111,7 @@ CONFIG_MTD_OOPS=y
|
||||
CONFIG_MTD_CFI=y
|
||||
CONFIG_MTD_CFI_INTELEXT=y
|
||||
CONFIG_MTD_NAND=y
|
||||
CONFIG_MTD_NAND_ECC_BCH=y
|
||||
CONFIG_MTD_NAND_OMAP2=y
|
||||
CONFIG_MTD_ONENAND=y
|
||||
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
|
||||
@ -317,7 +317,7 @@ CONFIG_EXT4_FS=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/mailbox.h>
|
||||
#include <linux/pl320-ipc.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
@ -917,6 +917,10 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
|
||||
static int __init omap_device_late_init(void)
|
||||
{
|
||||
bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
|
||||
|
||||
WARN(!of_have_populated_dt(),
|
||||
"legacy booting deprecated, please update to boot with .dts\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
omap_late_initcall_sync(omap_device_late_init);
|
||||
|
@ -1,5 +1,6 @@
|
||||
config ARM64
|
||||
def_bool y
|
||||
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
|
||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
@ -232,7 +233,7 @@ config ARM64_VA_BITS_42
|
||||
|
||||
config ARM64_VA_BITS_48
|
||||
bool "48-bit"
|
||||
depends on BROKEN
|
||||
depends on !ARM_SMMU
|
||||
|
||||
endchoice
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
bank-width = <4>;
|
||||
};
|
||||
|
||||
vram@2,00000000 {
|
||||
v2m_video_ram: vram@2,00000000 {
|
||||
compatible = "arm,vexpress-vram";
|
||||
reg = <2 0x00000000 0x00800000>;
|
||||
};
|
||||
@ -179,9 +179,42 @@
|
||||
clcd@1f0000 {
|
||||
compatible = "arm,pl111", "arm,primecell";
|
||||
reg = <0x1f0000 0x1000>;
|
||||
interrupt-names = "combined";
|
||||
interrupts = <14>;
|
||||
clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
|
||||
clock-names = "clcdclk", "apb_pclk";
|
||||
arm,pl11x,framebuffer = <0x18000000 0x00180000>;
|
||||
memory-region = <&v2m_video_ram>;
|
||||
max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
|
||||
|
||||
port {
|
||||
v2m_clcd_pads: endpoint {
|
||||
remote-endpoint = <&v2m_clcd_panel>;
|
||||
arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
|
||||
};
|
||||
};
|
||||
|
||||
panel {
|
||||
compatible = "panel-dpi";
|
||||
|
||||
port {
|
||||
v2m_clcd_panel: endpoint {
|
||||
remote-endpoint = <&v2m_clcd_pads>;
|
||||
};
|
||||
};
|
||||
|
||||
panel-timing {
|
||||
clock-frequency = <63500127>;
|
||||
hactive = <1024>;
|
||||
hback-porch = <152>;
|
||||
hfront-porch = <48>;
|
||||
hsync-len = <104>;
|
||||
vactive = <768>;
|
||||
vback-porch = <23>;
|
||||
vfront-porch = <3>;
|
||||
vsync-len = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtio_block@0130000 {
|
||||
|
@ -78,6 +78,7 @@ CONFIG_NET_XGENE=y
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIO_AMBAKMI=y
|
||||
CONFIG_LEGACY_PTY_COUNT=16
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
@ -90,6 +91,7 @@ CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_ARMCLCD=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
|
@ -37,8 +37,8 @@ typedef s32 compat_ssize_t;
|
||||
typedef s32 compat_time_t;
|
||||
typedef s32 compat_clock_t;
|
||||
typedef s32 compat_pid_t;
|
||||
typedef u32 __compat_uid_t;
|
||||
typedef u32 __compat_gid_t;
|
||||
typedef u16 __compat_uid_t;
|
||||
typedef u16 __compat_gid_t;
|
||||
typedef u16 __compat_uid16_t;
|
||||
typedef u16 __compat_gid16_t;
|
||||
typedef u32 __compat_uid32_t;
|
||||
|
@ -126,7 +126,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
|
||||
* that it will "exec", and that there is sufficient room for the brk.
|
||||
*/
|
||||
extern unsigned long randomize_et_dyn(unsigned long base);
|
||||
#define ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_64 / 3))
|
||||
#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
|
||||
|
||||
/*
|
||||
* When the program starts, a1 contains a pointer to a function to be
|
||||
@ -169,7 +169,7 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define COMPAT_ELF_PLATFORM ("v8l")
|
||||
#endif
|
||||
|
||||
#define COMPAT_ELF_ET_DYN_BASE (randomize_et_dyn(2 * TASK_SIZE_32 / 3))
|
||||
#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
|
||||
|
||||
/* AArch32 registers. */
|
||||
#define COMPAT_ELF_NGREG 18
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef __ASM_IRQ_WORK_H
|
||||
#define __ASM_IRQ_WORK_H
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#include <asm/smp.h>
|
||||
|
||||
static inline bool arch_irq_work_has_interrupt(void)
|
||||
@ -8,4 +10,13 @@ static inline bool arch_irq_work_has_interrupt(void)
|
||||
return !!__smp_cross_call;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline bool arch_irq_work_has_interrupt(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_IRQ_WORK_H */
|
||||
|
@ -89,7 +89,8 @@ static int __init uefi_init(void)
|
||||
*/
|
||||
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
|
||||
pr_err("System table signature incorrect\n");
|
||||
return -EINVAL;
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if ((efi.systab->hdr.revision >> 16) < 2)
|
||||
pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
|
||||
@ -103,6 +104,7 @@ static int __init uefi_init(void)
|
||||
for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
|
||||
vendor[i] = c16[i];
|
||||
vendor[i] = '\0';
|
||||
early_memunmap(c16, sizeof(vendor));
|
||||
}
|
||||
|
||||
pr_info("EFI v%u.%.02u by %s\n",
|
||||
@ -113,29 +115,11 @@ static int __init uefi_init(void)
|
||||
if (retval == 0)
|
||||
set_bit(EFI_CONFIG_TABLES, &efi.flags);
|
||||
|
||||
early_memunmap(c16, sizeof(vendor));
|
||||
out:
|
||||
early_memunmap(efi.systab, sizeof(efi_system_table_t));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __initdata char memory_type_name[][32] = {
|
||||
{"Reserved"},
|
||||
{"Loader Code"},
|
||||
{"Loader Data"},
|
||||
{"Boot Code"},
|
||||
{"Boot Data"},
|
||||
{"Runtime Code"},
|
||||
{"Runtime Data"},
|
||||
{"Conventional Memory"},
|
||||
{"Unusable Memory"},
|
||||
{"ACPI Reclaim Memory"},
|
||||
{"ACPI Memory NVS"},
|
||||
{"Memory Mapped I/O"},
|
||||
{"MMIO Port Space"},
|
||||
{"PAL Code"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Return true for RAM regions we want to permanently reserve.
|
||||
*/
|
||||
@ -166,10 +150,13 @@ static __init void reserve_regions(void)
|
||||
paddr = md->phys_addr;
|
||||
npages = md->num_pages;
|
||||
|
||||
if (uefi_debug)
|
||||
pr_info(" 0x%012llx-0x%012llx [%s]",
|
||||
if (uefi_debug) {
|
||||
char buf[64];
|
||||
|
||||
pr_info(" 0x%012llx-0x%012llx %s",
|
||||
paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
|
||||
memory_type_name[md->type]);
|
||||
efi_md_typeattr_format(buf, sizeof(buf), md));
|
||||
}
|
||||
|
||||
memrange_efi_to_native(&paddr, &npages);
|
||||
size = npages << PAGE_SHIFT;
|
||||
@ -393,11 +380,16 @@ static int __init arm64_enter_virtual_mode(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_info("Remapping and enabling EFI services.\n");
|
||||
|
||||
/* replace early memmap mapping with permanent mapping */
|
||||
mapsize = memmap.map_end - memmap.map;
|
||||
early_memunmap(memmap.map, mapsize);
|
||||
|
||||
if (efi_runtime_disabled()) {
|
||||
pr_info("EFI runtime services will be disabled.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_info("Remapping and enabling EFI services.\n");
|
||||
/* replace early memmap mapping with permanent mapping */
|
||||
memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
|
||||
mapsize);
|
||||
memmap.map_end = memmap.map + mapsize;
|
||||
|
@ -378,8 +378,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
|
||||
{
|
||||
return randomize_base(mm->brk);
|
||||
}
|
||||
|
||||
unsigned long randomize_et_dyn(unsigned long base)
|
||||
{
|
||||
return randomize_base(base);
|
||||
}
|
||||
|
@ -105,10 +105,10 @@ EXPORT_SYMBOL(ioremap_cache);
|
||||
|
||||
static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
|
||||
#if CONFIG_ARM64_PGTABLE_LEVELS > 2
|
||||
static pte_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss;
|
||||
static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss;
|
||||
#endif
|
||||
#if CONFIG_ARM64_PGTABLE_LEVELS > 3
|
||||
static pte_t bm_pud[PTRS_PER_PUD] __page_aligned_bss;
|
||||
static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss;
|
||||
#endif
|
||||
|
||||
static inline pud_t * __init early_ioremap_pud(unsigned long addr)
|
||||
|
@ -297,11 +297,15 @@ static void __init map_mem(void)
|
||||
* create_mapping requires puds, pmds and ptes to be allocated from
|
||||
* memory addressable from the initial direct kernel mapping.
|
||||
*
|
||||
* The initial direct kernel mapping, located at swapper_pg_dir,
|
||||
* gives us PUD_SIZE memory starting from PHYS_OFFSET (which must be
|
||||
* aligned to 2MB as per Documentation/arm64/booting.txt).
|
||||
* The initial direct kernel mapping, located at swapper_pg_dir, gives
|
||||
* us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
|
||||
* PHYS_OFFSET (which must be aligned to 2MB as per
|
||||
* Documentation/arm64/booting.txt).
|
||||
*/
|
||||
limit = PHYS_OFFSET + PUD_SIZE;
|
||||
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
|
||||
limit = PHYS_OFFSET + PMD_SIZE;
|
||||
else
|
||||
limit = PHYS_OFFSET + PUD_SIZE;
|
||||
memblock_set_current_limit(limit);
|
||||
|
||||
/* map all the memory banks */
|
||||
|
@ -30,12 +30,14 @@
|
||||
|
||||
#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
|
||||
|
||||
static struct kmem_cache *pgd_cache;
|
||||
|
||||
pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
{
|
||||
if (PGD_SIZE == PAGE_SIZE)
|
||||
return (pgd_t *)get_zeroed_page(GFP_KERNEL);
|
||||
else
|
||||
return kzalloc(PGD_SIZE, GFP_KERNEL);
|
||||
return kmem_cache_zalloc(pgd_cache, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
@ -43,5 +45,17 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
if (PGD_SIZE == PAGE_SIZE)
|
||||
free_page((unsigned long)pgd);
|
||||
else
|
||||
kfree(pgd);
|
||||
kmem_cache_free(pgd_cache, pgd);
|
||||
}
|
||||
|
||||
static int __init pgd_cache_init(void)
|
||||
{
|
||||
/*
|
||||
* Naturally aligned pgds required by the architecture.
|
||||
*/
|
||||
if (PGD_SIZE != PAGE_SIZE)
|
||||
pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
|
||||
SLAB_PANIC, NULL);
|
||||
return 0;
|
||||
}
|
||||
core_initcall(pgd_cache_init);
|
||||
|
@ -144,8 +144,12 @@
|
||||
|
||||
/* Data-processing (2 source) */
|
||||
/* Rd = Rn OP Rm */
|
||||
#define A64_UDIV(sf, Rd, Rn, Rm) aarch64_insn_gen_data2(Rd, Rn, Rm, \
|
||||
A64_VARIANT(sf), AARCH64_INSN_DATA2_UDIV)
|
||||
#define A64_DATA2(sf, Rd, Rn, Rm, type) aarch64_insn_gen_data2(Rd, Rn, Rm, \
|
||||
A64_VARIANT(sf), AARCH64_INSN_DATA2_##type)
|
||||
#define A64_UDIV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, UDIV)
|
||||
#define A64_LSLV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSLV)
|
||||
#define A64_LSRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSRV)
|
||||
#define A64_ASRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, ASRV)
|
||||
|
||||
/* Data-processing (3 source) */
|
||||
/* Rd = Ra + Rn * Rm */
|
||||
|
@ -19,12 +19,13 @@
|
||||
#define pr_fmt(fmt) "bpf_jit: " fmt
|
||||
|
||||
#include <linux/filter.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
|
||||
#include "bpf_jit.h"
|
||||
|
||||
@ -119,6 +120,14 @@ static inline int bpf2a64_offset(int bpf_to, int bpf_from,
|
||||
return to - from;
|
||||
}
|
||||
|
||||
static void jit_fill_hole(void *area, unsigned int size)
|
||||
{
|
||||
u32 *ptr;
|
||||
/* We are guaranteed to have aligned memory. */
|
||||
for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
|
||||
*ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT);
|
||||
}
|
||||
|
||||
static inline int epilogue_offset(const struct jit_ctx *ctx)
|
||||
{
|
||||
int to = ctx->offset[ctx->prog->len - 1];
|
||||
@ -196,6 +205,12 @@ static void build_epilogue(struct jit_ctx *ctx)
|
||||
emit(A64_RET(A64_LR), ctx);
|
||||
}
|
||||
|
||||
/* JITs an eBPF instruction.
|
||||
* Returns:
|
||||
* 0 - successfully JITed an 8-byte eBPF instruction.
|
||||
* >0 - successfully JITed a 16-byte eBPF instruction.
|
||||
* <0 - failed to JIT.
|
||||
*/
|
||||
static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
{
|
||||
const u8 code = insn->code;
|
||||
@ -252,6 +267,18 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
emit(A64_MUL(is64, tmp, tmp, src), ctx);
|
||||
emit(A64_SUB(is64, dst, dst, tmp), ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_LSH | BPF_X:
|
||||
emit(A64_LSLV(is64, dst, dst, src), ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_RSH | BPF_X:
|
||||
emit(A64_LSRV(is64, dst, dst, src), ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_ARSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_ARSH | BPF_X:
|
||||
emit(A64_ASRV(is64, dst, dst, src), ctx);
|
||||
break;
|
||||
/* dst = -dst */
|
||||
case BPF_ALU | BPF_NEG:
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
@ -443,6 +470,27 @@ emit_cond_jmp:
|
||||
emit(A64_B(jmp_offset), ctx);
|
||||
break;
|
||||
|
||||
/* dst = imm64 */
|
||||
case BPF_LD | BPF_IMM | BPF_DW:
|
||||
{
|
||||
const struct bpf_insn insn1 = insn[1];
|
||||
u64 imm64;
|
||||
|
||||
if (insn1.code != 0 || insn1.src_reg != 0 ||
|
||||
insn1.dst_reg != 0 || insn1.off != 0) {
|
||||
/* Note: verifier in BPF core must catch invalid
|
||||
* instructions.
|
||||
*/
|
||||
pr_err_once("Invalid BPF_LD_IMM64 instruction\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
imm64 = (u64)insn1.imm << 32 | imm;
|
||||
emit_a64_mov_i64(dst, imm64, ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* LDX: dst = *(size *)(src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_W:
|
||||
case BPF_LDX | BPF_MEM | BPF_H:
|
||||
@ -594,6 +642,10 @@ static int build_body(struct jit_ctx *ctx)
|
||||
ctx->offset[i] = ctx->idx;
|
||||
|
||||
ret = build_insn(insn, ctx);
|
||||
if (ret > 0) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -613,8 +665,10 @@ void bpf_jit_compile(struct bpf_prog *prog)
|
||||
|
||||
void bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_binary_header *header;
|
||||
struct jit_ctx ctx;
|
||||
int image_size;
|
||||
u8 *image_ptr;
|
||||
|
||||
if (!bpf_jit_enable)
|
||||
return;
|
||||
@ -636,23 +690,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
goto out;
|
||||
|
||||
build_prologue(&ctx);
|
||||
|
||||
build_epilogue(&ctx);
|
||||
|
||||
/* Now we know the actual image size. */
|
||||
image_size = sizeof(u32) * ctx.idx;
|
||||
ctx.image = module_alloc(image_size);
|
||||
if (unlikely(ctx.image == NULL))
|
||||
header = bpf_jit_binary_alloc(image_size, &image_ptr,
|
||||
sizeof(u32), jit_fill_hole);
|
||||
if (header == NULL)
|
||||
goto out;
|
||||
|
||||
/* 2. Now, the actual pass. */
|
||||
|
||||
ctx.image = (u32 *)image_ptr;
|
||||
ctx.idx = 0;
|
||||
|
||||
build_prologue(&ctx);
|
||||
|
||||
ctx.body_offset = ctx.idx;
|
||||
if (build_body(&ctx)) {
|
||||
module_free(NULL, ctx.image);
|
||||
bpf_jit_binary_free(header);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -663,17 +719,25 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
bpf_jit_dump(prog->len, image_size, 2, ctx.image);
|
||||
|
||||
bpf_flush_icache(ctx.image, ctx.image + ctx.idx);
|
||||
prog->bpf_func = (void *)ctx.image;
|
||||
prog->jited = 1;
|
||||
|
||||
set_memory_ro((unsigned long)header, header->pages);
|
||||
prog->bpf_func = (void *)ctx.image;
|
||||
prog->jited = true;
|
||||
out:
|
||||
kfree(ctx.offset);
|
||||
}
|
||||
|
||||
void bpf_jit_free(struct bpf_prog *prog)
|
||||
{
|
||||
if (prog->jited)
|
||||
module_free(NULL, prog->bpf_func);
|
||||
unsigned long addr = (unsigned long)prog->bpf_func & PAGE_MASK;
|
||||
struct bpf_binary_header *header = (void *)addr;
|
||||
|
||||
kfree(prog);
|
||||
if (!prog->jited)
|
||||
goto free_filter;
|
||||
|
||||
set_memory_rw(addr, header->pages);
|
||||
bpf_jit_binary_free(header);
|
||||
|
||||
free_filter:
|
||||
bpf_prog_unlock_free(prog);
|
||||
}
|
||||
|
@ -568,6 +568,7 @@ efi_init (void)
|
||||
{
|
||||
const char *unit;
|
||||
unsigned long size;
|
||||
char buf[64];
|
||||
|
||||
md = p;
|
||||
size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
@ -586,9 +587,10 @@ efi_init (void)
|
||||
unit = "KB";
|
||||
}
|
||||
|
||||
printk("mem%02d: type=%2u, attr=0x%016lx, "
|
||||
printk("mem%02d: %s "
|
||||
"range=[0x%016lx-0x%016lx) (%4lu%s)\n",
|
||||
i, md->type, md->attribute, md->phys_addr,
|
||||
i, efi_md_typeattr_format(buf, sizeof(buf), md),
|
||||
md->phys_addr,
|
||||
md->phys_addr + efi_md_size(md), size, unit);
|
||||
}
|
||||
}
|
||||
|
@ -2066,6 +2066,7 @@ config MIPS_CPS
|
||||
support is unavailable.
|
||||
|
||||
config MIPS_CPS_PM
|
||||
depends on MIPS_CPS
|
||||
select MIPS_CPC
|
||||
bool
|
||||
|
||||
|
@ -113,7 +113,7 @@ static void __init db120_pci_init(u8 *eeprom)
|
||||
ath79_register_pci();
|
||||
}
|
||||
#else
|
||||
static inline void db120_pci_init(void) {}
|
||||
static inline void db120_pci_init(u8 *eeprom) {}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init db120_setup(void)
|
||||
|
@ -806,15 +806,6 @@ void __init prom_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (octeon_is_simulation()) {
|
||||
/*
|
||||
* The simulator uses a mtdram device pre filled with
|
||||
* the filesystem. Also specify the calibration delay
|
||||
* to avoid calculating it every time.
|
||||
*/
|
||||
strcat(arcs_cmdline, " rw root=1f00 slram=root,0x40000000,+1073741824");
|
||||
}
|
||||
|
||||
mips_hpt_frequency = octeon_get_clock_rate();
|
||||
|
||||
octeon_init_cvmcount();
|
||||
|
@ -37,15 +37,15 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *);
|
||||
|
||||
#define cop2_present 1
|
||||
#define cop2_lazy_restore 1
|
||||
#define cop2_save(r) do { (r); } while (0)
|
||||
#define cop2_restore(r) do { (r); } while (0)
|
||||
#define cop2_save(r) do { (void)(r); } while (0)
|
||||
#define cop2_restore(r) do { (void)(r); } while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define cop2_present 0
|
||||
#define cop2_lazy_restore 0
|
||||
#define cop2_save(r) do { (r); } while (0)
|
||||
#define cop2_restore(r) do { (r); } while (0)
|
||||
#define cop2_save(r) do { (void)(r); } while (0)
|
||||
#define cop2_restore(r) do { (void)(r); } while (0)
|
||||
#endif
|
||||
|
||||
enum cu2_ops {
|
||||
|
@ -24,7 +24,7 @@ do { \
|
||||
asm volatile ( \
|
||||
"1: " load " %[tmp_dst], 0(%[tmp_src])\n" \
|
||||
" li %[tmp_err], 0\n" \
|
||||
"2:\n" \
|
||||
"2: .insn\n" \
|
||||
\
|
||||
".section .fixup, \"ax\"\n" \
|
||||
"3: li %[tmp_err], 1\n" \
|
||||
@ -46,7 +46,7 @@ do { \
|
||||
asm volatile ( \
|
||||
"1: " store " %[tmp_src], 0(%[tmp_dst])\n"\
|
||||
" li %[tmp_err], 0\n" \
|
||||
"2:\n" \
|
||||
"2: .insn\n" \
|
||||
\
|
||||
".section .fixup, \"ax\"\n" \
|
||||
"3: li %[tmp_err], 1\n" \
|
||||
|
@ -8,19 +8,12 @@ extern void (*cpu_wait)(void);
|
||||
extern void r4k_wait(void);
|
||||
extern asmlinkage void __r4k_wait(void);
|
||||
extern void r4k_wait_irqoff(void);
|
||||
extern void __pastwait(void);
|
||||
|
||||
static inline int using_rollback_handler(void)
|
||||
{
|
||||
return cpu_wait == r4k_wait;
|
||||
}
|
||||
|
||||
static inline int address_is_in_r4k_wait_irqoff(unsigned long addr)
|
||||
{
|
||||
return addr >= (unsigned long)r4k_wait_irqoff &&
|
||||
addr < (unsigned long)__pastwait;
|
||||
}
|
||||
|
||||
extern int mips_cpuidle_wait_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#ifndef _UAPI_ASM_PTRACE_H
|
||||
#define _UAPI_ASM_PTRACE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
|
||||
#define FPR_BASE 32
|
||||
#define PC 64
|
||||
|
@ -68,9 +68,6 @@ void r4k_wait_irqoff(void)
|
||||
" wait \n"
|
||||
" .set pop \n");
|
||||
local_irq_enable();
|
||||
__asm__(
|
||||
" .globl __pastwait \n"
|
||||
"__pastwait: \n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4,7 +4,7 @@ config PICVUE
|
||||
|
||||
config PICVUE_PROC
|
||||
tristate "PICVUE LCD display driver /proc interface"
|
||||
depends on PICVUE
|
||||
depends on PICVUE && PROC_FS
|
||||
|
||||
config DS1603
|
||||
bool "DS1603 RTC driver"
|
||||
|
@ -91,6 +91,7 @@ EXPORT_SYMBOL(clk_put);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned int rate_khz = rate / 1000;
|
||||
struct cpufreq_frequency_table *pos;
|
||||
int ret = 0;
|
||||
int regval;
|
||||
@ -107,9 +108,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
propagate_rate(clk);
|
||||
|
||||
cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table)
|
||||
if (rate == pos->frequency)
|
||||
if (rate_khz == pos->frequency)
|
||||
break;
|
||||
if (rate != pos->frequency)
|
||||
if (rate_khz != pos->frequency)
|
||||
return -ENOTSUPP;
|
||||
|
||||
clk->rate = rate;
|
||||
|
@ -1023,7 +1023,7 @@ emul:
|
||||
goto emul;
|
||||
|
||||
case cop1x_op:
|
||||
if (cpu_has_mips_4_5 || cpu_has_mips64)
|
||||
if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2)
|
||||
/* its one of ours */
|
||||
goto emul;
|
||||
|
||||
@ -1068,7 +1068,7 @@ emul:
|
||||
break;
|
||||
|
||||
case cop1x_op:
|
||||
if (!cpu_has_mips_4_5 && !cpu_has_mips64)
|
||||
if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2)
|
||||
return SIGILL;
|
||||
|
||||
sig = fpux_emu(xcp, ctx, ir, fault_addr);
|
||||
|
@ -1062,6 +1062,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
|
||||
struct mips_huge_tlb_info {
|
||||
int huge_pte;
|
||||
int restore_scratch;
|
||||
bool need_reload_pte;
|
||||
};
|
||||
|
||||
static struct mips_huge_tlb_info
|
||||
@ -1076,6 +1077,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
|
||||
|
||||
rv.huge_pte = scratch;
|
||||
rv.restore_scratch = 0;
|
||||
rv.need_reload_pte = false;
|
||||
|
||||
if (check_for_high_segbits) {
|
||||
UASM_i_MFC0(p, tmp, C0_BADVADDR);
|
||||
@ -1264,6 +1266,7 @@ static void build_r4000_tlb_refill_handler(void)
|
||||
} else {
|
||||
htlb_info.huge_pte = K0;
|
||||
htlb_info.restore_scratch = 0;
|
||||
htlb_info.need_reload_pte = true;
|
||||
vmalloc_mode = refill_noscratch;
|
||||
/*
|
||||
* create the plain linear handler
|
||||
@ -1300,7 +1303,8 @@ static void build_r4000_tlb_refill_handler(void)
|
||||
}
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
uasm_l_tlb_huge_update(&l, p);
|
||||
UASM_i_LW(&p, K0, 0, K1);
|
||||
if (htlb_info.need_reload_pte)
|
||||
UASM_i_LW(&p, htlb_info.huge_pte, 0, K1);
|
||||
build_huge_update_entries(&p, htlb_info.huge_pte, K1);
|
||||
build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
|
||||
htlb_info.restore_scratch);
|
||||
|
@ -5,8 +5,9 @@
|
||||
# Copyright (C) 2008 Wind River Systems, Inc.
|
||||
# written by Ralf Baechle <ralf@linux-mips.org>
|
||||
#
|
||||
obj-y := malta-amon.o malta-display.o malta-init.o \
|
||||
obj-y := malta-display.o malta-init.o \
|
||||
malta-int.o malta-memory.o malta-platform.o \
|
||||
malta-reset.o malta-setup.o malta-time.o
|
||||
|
||||
obj-$(CONFIG_MIPS_CMP) += malta-amon.o
|
||||
obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o
|
||||
|
@ -14,7 +14,6 @@ obj-y := sead3-lcd.o sead3-display.o sead3-init.o \
|
||||
sead3-setup.o sead3-time.o
|
||||
|
||||
obj-y += sead3-i2c-dev.o sead3-i2c.o \
|
||||
sead3-pic32-i2c-drv.o sead3-pic32-bus.o \
|
||||
leds-sead3.o sead3-leds.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
|
||||
|
@ -5,10 +5,8 @@
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <irq.h>
|
||||
|
||||
struct resource sead3_i2c_resources[] = {
|
||||
{
|
||||
@ -30,8 +28,4 @@ static int __init sead3_i2c_init(void)
|
||||
return platform_device_register(&sead3_i2c_device);
|
||||
}
|
||||
|
||||
module_init(sead3_i2c_init);
|
||||
|
||||
MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("I2C probe driver for SEAD3");
|
||||
device_initcall(sead3_i2c_init);
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define PIC32_NULL 0x00
|
||||
#define PIC32_RD 0x01
|
||||
#define PIC32_SYSRD 0x02
|
||||
#define PIC32_WR 0x10
|
||||
#define PIC32_SYSWR 0x20
|
||||
#define PIC32_IRQ_CLR 0x40
|
||||
#define PIC32_STATUS 0x80
|
||||
|
||||
#define DELAY() udelay(100) /* FIXME: needed? */
|
||||
|
||||
/* spinlock to ensure atomic access to PIC32 */
|
||||
static DEFINE_SPINLOCK(pic32_bus_lock);
|
||||
|
||||
/* FIXME: io_remap these */
|
||||
static void __iomem *bus_xfer = (void __iomem *)0xbf000600;
|
||||
static void __iomem *bus_status = (void __iomem *)0xbf000060;
|
||||
|
||||
static inline unsigned int ioready(void)
|
||||
{
|
||||
return readl(bus_status) & 1;
|
||||
}
|
||||
|
||||
static inline void wait_ioready(void)
|
||||
{
|
||||
do { } while (!ioready());
|
||||
}
|
||||
|
||||
static inline void wait_ioclear(void)
|
||||
{
|
||||
do { } while (ioready());
|
||||
}
|
||||
|
||||
static inline void check_ioclear(void)
|
||||
{
|
||||
if (ioready()) {
|
||||
pr_debug("ioclear: initially busy\n");
|
||||
do {
|
||||
(void) readl(bus_xfer);
|
||||
DELAY();
|
||||
} while (ioready());
|
||||
pr_debug("ioclear: cleared busy\n");
|
||||
}
|
||||
}
|
||||
|
||||
u32 pic32_bus_readl(u32 reg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 status, val;
|
||||
|
||||
spin_lock_irqsave(&pic32_bus_lock, flags);
|
||||
|
||||
check_ioclear();
|
||||
|
||||
writel((PIC32_RD << 24) | (reg & 0x00ffffff), bus_xfer);
|
||||
DELAY();
|
||||
wait_ioready();
|
||||
status = readl(bus_xfer);
|
||||
DELAY();
|
||||
val = readl(bus_xfer);
|
||||
wait_ioclear();
|
||||
|
||||
pr_debug("pic32_bus_readl: *%x -> %x (status=%x)\n", reg, val, status);
|
||||
|
||||
spin_unlock_irqrestore(&pic32_bus_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void pic32_bus_writel(u32 val, u32 reg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 status;
|
||||
|
||||
spin_lock_irqsave(&pic32_bus_lock, flags);
|
||||
|
||||
check_ioclear();
|
||||
|
||||
writel((PIC32_WR << 24) | (reg & 0x00ffffff), bus_xfer);
|
||||
DELAY();
|
||||
writel(val, bus_xfer);
|
||||
DELAY();
|
||||
wait_ioready();
|
||||
status = readl(bus_xfer);
|
||||
wait_ioclear();
|
||||
|
||||
pr_debug("pic32_bus_writel: *%x <- %x (status=%x)\n", reg, val, status);
|
||||
|
||||
spin_unlock_irqrestore(&pic32_bus_lock, flags);
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define PIC32_I2CxCON 0x0000
|
||||
#define PIC32_I2CxCONCLR 0x0004
|
||||
#define PIC32_I2CxCONSET 0x0008
|
||||
#define PIC32_I2CxCONINV 0x000C
|
||||
#define I2CCON_ON (1<<15)
|
||||
#define I2CCON_FRZ (1<<14)
|
||||
#define I2CCON_SIDL (1<<13)
|
||||
#define I2CCON_SCLREL (1<<12)
|
||||
#define I2CCON_STRICT (1<<11)
|
||||
#define I2CCON_A10M (1<<10)
|
||||
#define I2CCON_DISSLW (1<<9)
|
||||
#define I2CCON_SMEN (1<<8)
|
||||
#define I2CCON_GCEN (1<<7)
|
||||
#define I2CCON_STREN (1<<6)
|
||||
#define I2CCON_ACKDT (1<<5)
|
||||
#define I2CCON_ACKEN (1<<4)
|
||||
#define I2CCON_RCEN (1<<3)
|
||||
#define I2CCON_PEN (1<<2)
|
||||
#define I2CCON_RSEN (1<<1)
|
||||
#define I2CCON_SEN (1<<0)
|
||||
|
||||
#define PIC32_I2CxSTAT 0x0010
|
||||
#define PIC32_I2CxSTATCLR 0x0014
|
||||
#define PIC32_I2CxSTATSET 0x0018
|
||||
#define PIC32_I2CxSTATINV 0x001C
|
||||
#define I2CSTAT_ACKSTAT (1<<15)
|
||||
#define I2CSTAT_TRSTAT (1<<14)
|
||||
#define I2CSTAT_BCL (1<<10)
|
||||
#define I2CSTAT_GCSTAT (1<<9)
|
||||
#define I2CSTAT_ADD10 (1<<8)
|
||||
#define I2CSTAT_IWCOL (1<<7)
|
||||
#define I2CSTAT_I2COV (1<<6)
|
||||
#define I2CSTAT_DA (1<<5)
|
||||
#define I2CSTAT_P (1<<4)
|
||||
#define I2CSTAT_S (1<<3)
|
||||
#define I2CSTAT_RW (1<<2)
|
||||
#define I2CSTAT_RBF (1<<1)
|
||||
#define I2CSTAT_TBF (1<<0)
|
||||
|
||||
#define PIC32_I2CxADD 0x0020
|
||||
#define PIC32_I2CxADDCLR 0x0024
|
||||
#define PIC32_I2CxADDSET 0x0028
|
||||
#define PIC32_I2CxADDINV 0x002C
|
||||
#define PIC32_I2CxMSK 0x0030
|
||||
#define PIC32_I2CxMSKCLR 0x0034
|
||||
#define PIC32_I2CxMSKSET 0x0038
|
||||
#define PIC32_I2CxMSKINV 0x003C
|
||||
#define PIC32_I2CxBRG 0x0040
|
||||
#define PIC32_I2CxBRGCLR 0x0044
|
||||
#define PIC32_I2CxBRGSET 0x0048
|
||||
#define PIC32_I2CxBRGINV 0x004C
|
||||
#define PIC32_I2CxTRN 0x0050
|
||||
#define PIC32_I2CxTRNCLR 0x0054
|
||||
#define PIC32_I2CxTRNSET 0x0058
|
||||
#define PIC32_I2CxTRNINV 0x005C
|
||||
#define PIC32_I2CxRCV 0x0060
|
||||
|
||||
struct i2c_platform_data {
|
||||
u32 base;
|
||||
struct i2c_adapter adap;
|
||||
u32 xfer_timeout;
|
||||
u32 ack_timeout;
|
||||
u32 ctl_timeout;
|
||||
};
|
||||
|
||||
extern u32 pic32_bus_readl(u32 reg);
|
||||
extern void pic32_bus_writel(u32 val, u32 reg);
|
||||
|
||||
static inline void
|
||||
StartI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("StartI2C\n");
|
||||
pic32_bus_writel(I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
StopI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("StopI2C\n");
|
||||
pic32_bus_writel(I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
AckI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("AckI2C\n");
|
||||
pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
|
||||
pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
NotAckI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("NakI2C\n");
|
||||
pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
|
||||
pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline int
|
||||
IdleI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_debug("IdleI2C\n");
|
||||
for (i = 0; i < adap->ctl_timeout; i++) {
|
||||
if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
|
||||
(I2CCON_ACKEN | I2CCON_RCEN | I2CCON_PEN | I2CCON_RSEN |
|
||||
I2CCON_SEN)) == 0) &&
|
||||
((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
|
||||
(I2CSTAT_TRSTAT)) == 0))
|
||||
return 0;
|
||||
udelay(1);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
MasterWriteI2C(struct i2c_platform_data *adap, u32 byte)
|
||||
{
|
||||
pr_debug("MasterWriteI2C\n");
|
||||
|
||||
pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
|
||||
|
||||
return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_IWCOL;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
MasterReadI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("MasterReadI2C\n");
|
||||
|
||||
pic32_bus_writel(I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
|
||||
|
||||
while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & I2CCON_RCEN)
|
||||
;
|
||||
|
||||
pic32_bus_writel(I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
|
||||
|
||||
return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
|
||||
}
|
||||
|
||||
static int
|
||||
do_address(struct i2c_platform_data *adap, unsigned int addr, int rd)
|
||||
{
|
||||
pr_debug("doaddress\n");
|
||||
|
||||
IdleI2C(adap);
|
||||
StartI2C(adap);
|
||||
IdleI2C(adap);
|
||||
|
||||
addr <<= 1;
|
||||
if (rd)
|
||||
addr |= 1;
|
||||
|
||||
if (MasterWriteI2C(adap, addr))
|
||||
return -EIO;
|
||||
IdleI2C(adap);
|
||||
if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_ACKSTAT)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_read(struct i2c_platform_data *adap, unsigned char *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int i;
|
||||
u32 data;
|
||||
|
||||
pr_debug("i2c_read\n");
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
data = MasterReadI2C(adap);
|
||||
buf[i++] = data;
|
||||
if (i < len)
|
||||
AckI2C(adap);
|
||||
else
|
||||
NotAckI2C(adap);
|
||||
}
|
||||
|
||||
StopI2C(adap);
|
||||
IdleI2C(adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_write(struct i2c_platform_data *adap, unsigned char *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int i;
|
||||
u32 data;
|
||||
|
||||
pr_debug("i2c_write\n");
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
data = buf[i];
|
||||
if (MasterWriteI2C(adap, data))
|
||||
return -EIO;
|
||||
IdleI2C(adap);
|
||||
if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
|
||||
I2CSTAT_ACKSTAT)
|
||||
return -EIO;
|
||||
i++;
|
||||
}
|
||||
|
||||
StopI2C(adap);
|
||||
IdleI2C(adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
platform_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
struct i2c_platform_data *adap = i2c_adap->algo_data;
|
||||
struct i2c_msg *p;
|
||||
int i, err = 0;
|
||||
|
||||
pr_debug("platform_xfer\n");
|
||||
for (i = 0; i < num; i++) {
|
||||
#define __BUFSIZE 80
|
||||
int ii;
|
||||
static char buf[__BUFSIZE];
|
||||
char *b = buf;
|
||||
|
||||
p = &msgs[i];
|
||||
b += sprintf(buf, " [%d bytes]", p->len);
|
||||
if ((p->flags & I2C_M_RD) == 0) {
|
||||
for (ii = 0; ii < p->len; ii++) {
|
||||
if (b < &buf[__BUFSIZE-4]) {
|
||||
b += sprintf(b, " %02x", p->buf[ii]);
|
||||
} else {
|
||||
strcat(b, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pr_debug("xfer%d: DevAddr: %04x Op:%s Data:%s\n", i, p->addr,
|
||||
(p->flags & I2C_M_RD) ? "Rd" : "Wr", buf);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; !err && i < num; i++) {
|
||||
p = &msgs[i];
|
||||
err = do_address(adap, p->addr, p->flags & I2C_M_RD);
|
||||
if (err || !p->len)
|
||||
continue;
|
||||
if (p->flags & I2C_M_RD)
|
||||
err = i2c_read(adap, p->buf, p->len);
|
||||
else
|
||||
err = i2c_write(adap, p->buf, p->len);
|
||||
}
|
||||
|
||||
/* Return the number of messages processed, or the error code. */
|
||||
if (err == 0)
|
||||
err = num;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32
|
||||
platform_func(struct i2c_adapter *adap)
|
||||
{
|
||||
pr_debug("platform_algo\n");
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm platform_algo = {
|
||||
.master_xfer = platform_xfer,
|
||||
.functionality = platform_func,
|
||||
};
|
||||
|
||||
static void i2c_platform_setup(struct i2c_platform_data *priv)
|
||||
{
|
||||
pr_debug("i2c_platform_setup\n");
|
||||
|
||||
pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
|
||||
pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
|
||||
pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONSET);
|
||||
pic32_bus_writel((I2CSTAT_BCL | I2CSTAT_IWCOL),
|
||||
(priv->base + PIC32_I2CxSTATCLR));
|
||||
}
|
||||
|
||||
static void i2c_platform_disable(struct i2c_platform_data *priv)
|
||||
{
|
||||
pr_debug("i2c_platform_disable\n");
|
||||
}
|
||||
|
||||
static int i2c_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv;
|
||||
struct resource *r;
|
||||
int ret;
|
||||
|
||||
pr_debug("i2c_platform_probe\n");
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r)
|
||||
return -ENODEV;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct i2c_platform_data),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* FIXME: need to allocate resource in PIC32 space */
|
||||
#if 0
|
||||
priv->base = bus_request_region(r->start, resource_size(r),
|
||||
pdev->name);
|
||||
#else
|
||||
priv->base = r->start;
|
||||
#endif
|
||||
if (!priv->base)
|
||||
return -EBUSY;
|
||||
|
||||
priv->xfer_timeout = 200;
|
||||
priv->ack_timeout = 200;
|
||||
priv->ctl_timeout = 200;
|
||||
|
||||
priv->adap.nr = pdev->id;
|
||||
priv->adap.algo = &platform_algo;
|
||||
priv->adap.algo_data = priv;
|
||||
priv->adap.dev.parent = &pdev->dev;
|
||||
strlcpy(priv->adap.name, "PIC32 I2C", sizeof(priv->adap.name));
|
||||
|
||||
i2c_platform_setup(priv);
|
||||
|
||||
ret = i2c_add_numbered_adapter(&priv->adap);
|
||||
if (ret) {
|
||||
i2c_platform_disable(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
pr_debug("i2c_platform_remove\n");
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
i2c_del_adapter(&priv->adap);
|
||||
i2c_platform_disable(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int
|
||||
i2c_platform_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
dev_dbg(&pdev->dev, "i2c_platform_disable\n");
|
||||
i2c_platform_disable(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_platform_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
dev_dbg(&pdev->dev, "i2c_platform_setup\n");
|
||||
i2c_platform_setup(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define i2c_platform_suspend NULL
|
||||
#define i2c_platform_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver i2c_platform_driver = {
|
||||
.driver = {
|
||||
.name = "i2c_pic32",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = i2c_platform_probe,
|
||||
.remove = i2c_platform_remove,
|
||||
.suspend = i2c_platform_suspend,
|
||||
.resume = i2c_platform_resume,
|
||||
};
|
||||
|
||||
static int __init
|
||||
i2c_platform_init(void)
|
||||
{
|
||||
pr_debug("i2c_platform_init\n");
|
||||
return platform_driver_register(&i2c_platform_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
i2c_platform_exit(void)
|
||||
{
|
||||
pr_debug("i2c_platform_exit\n");
|
||||
platform_driver_unregister(&i2c_platform_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
|
||||
MODULE_DESCRIPTION("PIC32 I2C driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(i2c_platform_init);
|
||||
module_exit(i2c_platform_exit);
|
@ -215,17 +215,12 @@ static int ltq_pci_probe(struct platform_device *pdev)
|
||||
|
||||
pci_clear_flags(PCI_PROBE_ONLY);
|
||||
|
||||
res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
res_bridge = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res_cfg || !res_bridge) {
|
||||
dev_err(&pdev->dev, "missing memory resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ltq_pci_membase = devm_ioremap_resource(&pdev->dev, res_bridge);
|
||||
if (IS_ERR(ltq_pci_membase))
|
||||
return PTR_ERR(ltq_pci_membase);
|
||||
|
||||
res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ltq_pci_mapped_cfg = devm_ioremap_resource(&pdev->dev, res_cfg);
|
||||
if (IS_ERR(ltq_pci_mapped_cfg))
|
||||
return PTR_ERR(ltq_pci_mapped_cfg);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <msp_int.h>
|
||||
|
||||
|
@ -131,11 +131,11 @@ static int msp_cic_irq_set_affinity(struct irq_data *d,
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
unsigned int mtflags;
|
||||
unsigned long imask = (1 << (irq - MSP_CIC_INTBASE));
|
||||
unsigned long imask = (1 << (d->irq - MSP_CIC_INTBASE));
|
||||
volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG;
|
||||
|
||||
/* timer balancing should be disabled in kernel code */
|
||||
BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER);
|
||||
BUG_ON(d->irq == MSP_INT_VPE0_TIMER || d->irq == MSP_INT_VPE1_TIMER);
|
||||
|
||||
LOCK_CORE(flags, mtflags);
|
||||
/* enable if any of each VPE's TCs require this IRQ */
|
||||
|
@ -25,3 +25,4 @@ obj-$(CONFIG_SIBYTE_RHONE) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_SENTOSA) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_SWARM) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_BIGSUR) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_LITTLESUR) += swarm/
|
||||
|
@ -48,7 +48,6 @@ CONFIG_KEXEC=y
|
||||
CONFIG_IRQ_ALL_CPUS=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_PPC_64K_PAGES=y
|
||||
CONFIG_PPC_SUBPAGE_PROT=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
@ -138,6 +137,7 @@ CONFIG_NETCONSOLE=y
|
||||
CONFIG_NETPOLL_TRAP=y
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_VHOST_NET=m
|
||||
CONFIG_VORTEX=y
|
||||
CONFIG_ACENIC=m
|
||||
CONFIG_ACENIC_OMIT_TIGON_I=y
|
||||
@ -303,4 +303,9 @@ CONFIG_CRYPTO_LZO=m
|
||||
# CONFIG_CRYPTO_ANSI_CPRNG is not set
|
||||
CONFIG_CRYPTO_DEV_NX=y
|
||||
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_KVM_BOOK3S_64=m
|
||||
CONFIG_KVM_BOOK3S_64_HV=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
|
@ -71,9 +71,10 @@ struct device_node;
|
||||
|
||||
#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
|
||||
#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */
|
||||
#define EEH_PE_RESET (1 << 2) /* PE reset in progress */
|
||||
#define EEH_PE_CFG_BLOCKED (1 << 2) /* Block config access */
|
||||
|
||||
#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
|
||||
#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */
|
||||
|
||||
struct eeh_pe {
|
||||
int type; /* PE type: PHB/Bus/Device */
|
||||
|
@ -34,7 +34,7 @@
|
||||
do { \
|
||||
(regs)->result = 0; \
|
||||
(regs)->nip = __ip; \
|
||||
(regs)->gpr[1] = *(unsigned long *)__get_SP(); \
|
||||
(regs)->gpr[1] = current_stack_pointer(); \
|
||||
asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user