mirror of
https://github.com/torvalds/linux.git
synced 2026-08-02 13:22:02 +02:00
Snap for 8912470 from 9ba9c267b2 to android-mainline-keystone-qcom-release
Change-Id: I6618a44709f19ffb1fc78a82644883aba2c0a343
This commit is contained in:
commit
c4a88a980e
7
.mailmap
7
.mailmap
|
|
@ -60,6 +60,10 @@ Arnd Bergmann <arnd@arndb.de>
|
||||||
Atish Patra <atishp@atishpatra.org> <atish.patra@wdc.com>
|
Atish Patra <atishp@atishpatra.org> <atish.patra@wdc.com>
|
||||||
Axel Dyks <xl@xlsigned.net>
|
Axel Dyks <xl@xlsigned.net>
|
||||||
Axel Lin <axel.lin@gmail.com>
|
Axel Lin <axel.lin@gmail.com>
|
||||||
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@linaro.org>
|
||||||
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com>
|
||||||
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com>
|
||||||
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com>
|
||||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
||||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
||||||
Ben Gardner <bgardner@wabtec.com>
|
Ben Gardner <bgardner@wabtec.com>
|
||||||
|
|
@ -135,6 +139,8 @@ Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
|
||||||
Frank Zago <fzago@systemfabricworks.com>
|
Frank Zago <fzago@systemfabricworks.com>
|
||||||
Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
|
Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
|
||||||
Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
|
Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
|
||||||
|
Gao Xiang <xiang@kernel.org> <hsiangkao@linux.alibaba.com>
|
||||||
|
Gao Xiang <xiang@kernel.org> <hsiangkao@redhat.com>
|
||||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
|
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
|
||||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
|
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
|
||||||
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com>
|
Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com>
|
||||||
|
|
@ -371,6 +377,7 @@ Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>
|
||||||
Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
|
Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
|
||||||
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
|
Sebastian Reichel <sre@kernel.org> <sre@debian.org>
|
||||||
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
|
Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
|
||||||
|
Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>
|
||||||
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
|
Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
|
||||||
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
|
Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
|
||||||
Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>
|
Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com>
|
||||||
|
|
|
||||||
4
CREDITS
4
CREDITS
|
|
@ -627,6 +627,10 @@ S: 48287 Sawleaf
|
||||||
S: Fremont, California 94539
|
S: Fremont, California 94539
|
||||||
S: USA
|
S: USA
|
||||||
|
|
||||||
|
N: Tomas Cech
|
||||||
|
E: sleep_walker@suse.com
|
||||||
|
D: arm/palm treo support
|
||||||
|
|
||||||
N: Florent Chabaud
|
N: Florent Chabaud
|
||||||
E: florent.chabaud@polytechnique.org
|
E: florent.chabaud@polytechnique.org
|
||||||
D: software suspend
|
D: software suspend
|
||||||
|
|
|
||||||
|
|
@ -3184,6 +3184,7 @@
|
||||||
no_entry_flush [PPC]
|
no_entry_flush [PPC]
|
||||||
no_uaccess_flush [PPC]
|
no_uaccess_flush [PPC]
|
||||||
mmio_stale_data=off [X86]
|
mmio_stale_data=off [X86]
|
||||||
|
retbleed=off [X86]
|
||||||
|
|
||||||
Exceptions:
|
Exceptions:
|
||||||
This does not have any effect on
|
This does not have any effect on
|
||||||
|
|
@ -3206,6 +3207,7 @@
|
||||||
mds=full,nosmt [X86]
|
mds=full,nosmt [X86]
|
||||||
tsx_async_abort=full,nosmt [X86]
|
tsx_async_abort=full,nosmt [X86]
|
||||||
mmio_stale_data=full,nosmt [X86]
|
mmio_stale_data=full,nosmt [X86]
|
||||||
|
retbleed=auto,nosmt [X86]
|
||||||
|
|
||||||
mminit_loglevel=
|
mminit_loglevel=
|
||||||
[KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
|
[KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
|
||||||
|
|
@ -5804,6 +5806,24 @@
|
||||||
expediting. Set to zero to disable automatic
|
expediting. Set to zero to disable automatic
|
||||||
expediting.
|
expediting.
|
||||||
|
|
||||||
|
srcutree.srcu_max_nodelay [KNL]
|
||||||
|
Specifies the number of no-delay instances
|
||||||
|
per jiffy for which the SRCU grace period
|
||||||
|
worker thread will be rescheduled with zero
|
||||||
|
delay. Beyond this limit, worker thread will
|
||||||
|
be rescheduled with a sleep delay of one jiffy.
|
||||||
|
|
||||||
|
srcutree.srcu_max_nodelay_phase [KNL]
|
||||||
|
Specifies the per-grace-period phase, number of
|
||||||
|
non-sleeping polls of readers. Beyond this limit,
|
||||||
|
grace period worker thread will be rescheduled
|
||||||
|
with a sleep delay of one jiffy, between each
|
||||||
|
rescan of the readers, for a grace period phase.
|
||||||
|
|
||||||
|
srcutree.srcu_retry_check_delay [KNL]
|
||||||
|
Specifies number of microseconds of non-sleeping
|
||||||
|
delay between each non-sleeping poll of readers.
|
||||||
|
|
||||||
srcutree.small_contention_lim [KNL]
|
srcutree.small_contention_lim [KNL]
|
||||||
Specifies the number of update-side contention
|
Specifies the number of update-side contention
|
||||||
events per jiffy will be tolerated before
|
events per jiffy will be tolerated before
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ if:
|
||||||
- allwinner,sun8i-a83t-display-engine
|
- allwinner,sun8i-a83t-display-engine
|
||||||
- allwinner,sun8i-r40-display-engine
|
- allwinner,sun8i-r40-display-engine
|
||||||
- allwinner,sun9i-a80-display-engine
|
- allwinner,sun9i-a80-display-engine
|
||||||
|
- allwinner,sun20i-d1-display-engine
|
||||||
- allwinner,sun50i-a64-display-engine
|
- allwinner,sun50i-a64-display-engine
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
|
|
||||||
|
|
@ -167,10 +167,8 @@ properties:
|
||||||
- in-band-status
|
- in-band-status
|
||||||
|
|
||||||
fixed-link:
|
fixed-link:
|
||||||
allOf:
|
oneOf:
|
||||||
- if:
|
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||||
type: array
|
|
||||||
then:
|
|
||||||
deprecated: true
|
deprecated: true
|
||||||
items:
|
items:
|
||||||
- minimum: 0
|
- minimum: 0
|
||||||
|
|
@ -196,11 +194,8 @@ properties:
|
||||||
description:
|
description:
|
||||||
Asymmetric pause configuration. 0 for no asymmetric
|
Asymmetric pause configuration. 0 for no asymmetric
|
||||||
pause, 1 for asymmetric pause
|
pause, 1 for asymmetric pause
|
||||||
|
- type: object
|
||||||
|
additionalProperties: false
|
||||||
- if:
|
|
||||||
type: object
|
|
||||||
then:
|
|
||||||
properties:
|
properties:
|
||||||
speed:
|
speed:
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ properties:
|
||||||
Should specify the gpio for phy reset.
|
Should specify the gpio for phy reset.
|
||||||
|
|
||||||
phy-reset-duration:
|
phy-reset-duration:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
deprecated: true
|
deprecated: true
|
||||||
description:
|
description:
|
||||||
Reset duration in milliseconds. Should present only if property
|
Reset duration in milliseconds. Should present only if property
|
||||||
|
|
@ -191,12 +192,14 @@ properties:
|
||||||
and 1 millisecond will be used instead.
|
and 1 millisecond will be used instead.
|
||||||
|
|
||||||
phy-reset-active-high:
|
phy-reset-active-high:
|
||||||
|
type: boolean
|
||||||
deprecated: true
|
deprecated: true
|
||||||
description:
|
description:
|
||||||
If present then the reset sequence using the GPIO specified in the
|
If present then the reset sequence using the GPIO specified in the
|
||||||
"phy-reset-gpios" property is reversed (H=reset state, L=operation state).
|
"phy-reset-gpios" property is reversed (H=reset state, L=operation state).
|
||||||
|
|
||||||
phy-reset-post-delay:
|
phy-reset-post-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
deprecated: true
|
deprecated: true
|
||||||
description:
|
description:
|
||||||
Post reset delay in milliseconds. If present then a delay of phy-reset-post-delay
|
Post reset delay in milliseconds. If present then a delay of phy-reset-post-delay
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
title: Qualcomm Atheros ath9k wireless devices Generic Binding
|
title: Qualcomm Atheros ath9k wireless devices Generic Binding
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Kalle Valo <kvalo@codeaurora.org>
|
- Toke Høiland-Jørgensen <toke@toke.dk>
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
This node provides properties for configuring the ath9k wireless device.
|
This node provides properties for configuring the ath9k wireless device.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
title: Qualcomm Technologies ath11k wireless devices Generic Binding
|
title: Qualcomm Technologies ath11k wireless devices Generic Binding
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Kalle Valo <kvalo@codeaurora.org>
|
- Kalle Valo <kvalo@kernel.org>
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
These are dt entries for Qualcomm Technologies, Inc. IEEE 802.11ax
|
These are dt entries for Qualcomm Technologies, Inc. IEEE 802.11ax
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@ properties:
|
||||||
- qcom,sc7280-lpass-cpu
|
- qcom,sc7280-lpass-cpu
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
minItems: 2
|
minItems: 1
|
||||||
maxItems: 6
|
maxItems: 6
|
||||||
description: LPAIF core registers
|
description: LPAIF core registers
|
||||||
|
|
||||||
reg-names:
|
reg-names:
|
||||||
minItems: 2
|
minItems: 1
|
||||||
maxItems: 6
|
maxItems: 6
|
||||||
|
|
||||||
clocks:
|
clocks:
|
||||||
|
|
@ -42,12 +42,12 @@ properties:
|
||||||
maxItems: 10
|
maxItems: 10
|
||||||
|
|
||||||
interrupts:
|
interrupts:
|
||||||
minItems: 2
|
minItems: 1
|
||||||
maxItems: 4
|
maxItems: 4
|
||||||
description: LPAIF DMA buffer interrupt
|
description: LPAIF DMA buffer interrupt
|
||||||
|
|
||||||
interrupt-names:
|
interrupt-names:
|
||||||
minItems: 2
|
minItems: 1
|
||||||
maxItems: 4
|
maxItems: 4
|
||||||
|
|
||||||
qcom,adsp:
|
qcom,adsp:
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ through which it can issue requests and negotiate::
|
||||||
void (*issue_read)(struct netfs_io_subrequest *subreq);
|
void (*issue_read)(struct netfs_io_subrequest *subreq);
|
||||||
bool (*is_still_valid)(struct netfs_io_request *rreq);
|
bool (*is_still_valid)(struct netfs_io_request *rreq);
|
||||||
int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
|
int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
|
||||||
struct folio *folio, void **_fsdata);
|
struct folio **foliop, void **_fsdata);
|
||||||
void (*done)(struct netfs_io_request *rreq);
|
void (*done)(struct netfs_io_request *rreq);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -381,8 +381,10 @@ The operations are as follows:
|
||||||
allocated/grabbed the folio to be modified to allow the filesystem to flush
|
allocated/grabbed the folio to be modified to allow the filesystem to flush
|
||||||
conflicting state before allowing it to be modified.
|
conflicting state before allowing it to be modified.
|
||||||
|
|
||||||
It should return 0 if everything is now fine, -EAGAIN if the folio should be
|
It may unlock and discard the folio it was given and set the caller's folio
|
||||||
regrabbed and any other error code to abort the operation.
|
pointer to NULL. It should return 0 if everything is now fine (``*foliop``
|
||||||
|
left set) or the op should be retried (``*foliop`` cleared) and any other
|
||||||
|
error code to abort the operation.
|
||||||
|
|
||||||
* ``done``
|
* ``done``
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -503,26 +503,108 @@ per-port PHY specific details: interface connection, MDIO bus location, etc.
|
||||||
Driver development
|
Driver development
|
||||||
==================
|
==================
|
||||||
|
|
||||||
DSA switch drivers need to implement a dsa_switch_ops structure which will
|
DSA switch drivers need to implement a ``dsa_switch_ops`` structure which will
|
||||||
contain the various members described below.
|
contain the various members described below.
|
||||||
|
|
||||||
``register_switch_driver()`` registers this dsa_switch_ops in its internal list
|
Probing, registration and device lifetime
|
||||||
of drivers to probe for. ``unregister_switch_driver()`` does the exact opposite.
|
-----------------------------------------
|
||||||
|
|
||||||
Unless requested differently by setting the priv_size member accordingly, DSA
|
DSA switches are regular ``device`` structures on buses (be they platform, SPI,
|
||||||
does not allocate any driver private context space.
|
I2C, MDIO or otherwise). The DSA framework is not involved in their probing
|
||||||
|
with the device core.
|
||||||
|
|
||||||
|
Switch registration from the perspective of a driver means passing a valid
|
||||||
|
``struct dsa_switch`` pointer to ``dsa_register_switch()``, usually from the
|
||||||
|
switch driver's probing function. The following members must be valid in the
|
||||||
|
provided structure:
|
||||||
|
|
||||||
|
- ``ds->dev``: will be used to parse the switch's OF node or platform data.
|
||||||
|
|
||||||
|
- ``ds->num_ports``: will be used to create the port list for this switch, and
|
||||||
|
to validate the port indices provided in the OF node.
|
||||||
|
|
||||||
|
- ``ds->ops``: a pointer to the ``dsa_switch_ops`` structure holding the DSA
|
||||||
|
method implementations.
|
||||||
|
|
||||||
|
- ``ds->priv``: backpointer to a driver-private data structure which can be
|
||||||
|
retrieved in all further DSA method callbacks.
|
||||||
|
|
||||||
|
In addition, the following flags in the ``dsa_switch`` structure may optionally
|
||||||
|
be configured to obtain driver-specific behavior from the DSA core. Their
|
||||||
|
behavior when set is documented through comments in ``include/net/dsa.h``.
|
||||||
|
|
||||||
|
- ``ds->vlan_filtering_is_global``
|
||||||
|
|
||||||
|
- ``ds->needs_standalone_vlan_filtering``
|
||||||
|
|
||||||
|
- ``ds->configure_vlan_while_not_filtering``
|
||||||
|
|
||||||
|
- ``ds->untag_bridge_pvid``
|
||||||
|
|
||||||
|
- ``ds->assisted_learning_on_cpu_port``
|
||||||
|
|
||||||
|
- ``ds->mtu_enforcement_ingress``
|
||||||
|
|
||||||
|
- ``ds->fdb_isolation``
|
||||||
|
|
||||||
|
Internally, DSA keeps an array of switch trees (group of switches) global to
|
||||||
|
the kernel, and attaches a ``dsa_switch`` structure to a tree on registration.
|
||||||
|
The tree ID to which the switch is attached is determined by the first u32
|
||||||
|
number of the ``dsa,member`` property of the switch's OF node (0 if missing).
|
||||||
|
The switch ID within the tree is determined by the second u32 number of the
|
||||||
|
same OF property (0 if missing). Registering multiple switches with the same
|
||||||
|
switch ID and tree ID is illegal and will cause an error. Using platform data,
|
||||||
|
a single switch and a single switch tree is permitted.
|
||||||
|
|
||||||
|
In case of a tree with multiple switches, probing takes place asymmetrically.
|
||||||
|
The first N-1 callers of ``dsa_register_switch()`` only add their ports to the
|
||||||
|
port list of the tree (``dst->ports``), each port having a backpointer to its
|
||||||
|
associated switch (``dp->ds``). Then, these switches exit their
|
||||||
|
``dsa_register_switch()`` call early, because ``dsa_tree_setup_routing_table()``
|
||||||
|
has determined that the tree is not yet complete (not all ports referenced by
|
||||||
|
DSA links are present in the tree's port list). The tree becomes complete when
|
||||||
|
the last switch calls ``dsa_register_switch()``, and this triggers the effective
|
||||||
|
continuation of initialization (including the call to ``ds->ops->setup()``) for
|
||||||
|
all switches within that tree, all as part of the calling context of the last
|
||||||
|
switch's probe function.
|
||||||
|
|
||||||
|
The opposite of registration takes place when calling ``dsa_unregister_switch()``,
|
||||||
|
which removes a switch's ports from the port list of the tree. The entire tree
|
||||||
|
is torn down when the first switch unregisters.
|
||||||
|
|
||||||
|
It is mandatory for DSA switch drivers to implement the ``shutdown()`` callback
|
||||||
|
of their respective bus, and call ``dsa_switch_shutdown()`` from it (a minimal
|
||||||
|
version of the full teardown performed by ``dsa_unregister_switch()``).
|
||||||
|
The reason is that DSA keeps a reference on the master net device, and if the
|
||||||
|
driver for the master device decides to unbind on shutdown, DSA's reference
|
||||||
|
will block that operation from finalizing.
|
||||||
|
|
||||||
|
Either ``dsa_switch_shutdown()`` or ``dsa_unregister_switch()`` must be called,
|
||||||
|
but not both, and the device driver model permits the bus' ``remove()`` method
|
||||||
|
to be called even if ``shutdown()`` was already called. Therefore, drivers are
|
||||||
|
expected to implement a mutual exclusion method between ``remove()`` and
|
||||||
|
``shutdown()`` by setting their drvdata to NULL after any of these has run, and
|
||||||
|
checking whether the drvdata is NULL before proceeding to take any action.
|
||||||
|
|
||||||
|
After ``dsa_switch_shutdown()`` or ``dsa_unregister_switch()`` was called, no
|
||||||
|
further callbacks via the provided ``dsa_switch_ops`` may take place, and the
|
||||||
|
driver may free the data structures associated with the ``dsa_switch``.
|
||||||
|
|
||||||
Switch configuration
|
Switch configuration
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
- ``tag_protocol``: this is to indicate what kind of tagging protocol is supported,
|
- ``get_tag_protocol``: this is to indicate what kind of tagging protocol is
|
||||||
should be a valid value from the ``dsa_tag_protocol`` enum
|
supported, should be a valid value from the ``dsa_tag_protocol`` enum.
|
||||||
|
The returned information does not have to be static; the driver is passed the
|
||||||
|
CPU port number, as well as the tagging protocol of a possibly stacked
|
||||||
|
upstream switch, in case there are hardware limitations in terms of supported
|
||||||
|
tag formats.
|
||||||
|
|
||||||
- ``probe``: probe routine which will be invoked by the DSA platform device upon
|
- ``change_tag_protocol``: when the default tagging protocol has compatibility
|
||||||
registration to test for the presence/absence of a switch device. For MDIO
|
problems with the master or other issues, the driver may support changing it
|
||||||
devices, it is recommended to issue a read towards internal registers using
|
at runtime, either through a device tree property or through sysfs. In that
|
||||||
the switch pseudo-PHY and return whether this is a supported device. For other
|
case, further calls to ``get_tag_protocol`` should report the protocol in
|
||||||
buses, return a non-NULL string
|
current use.
|
||||||
|
|
||||||
- ``setup``: setup function for the switch, this function is responsible for setting
|
- ``setup``: setup function for the switch, this function is responsible for setting
|
||||||
up the ``dsa_switch_ops`` private structure with all it needs: register maps,
|
up the ``dsa_switch_ops`` private structure with all it needs: register maps,
|
||||||
|
|
@ -535,7 +617,17 @@ Switch configuration
|
||||||
fully configured and ready to serve any kind of request. It is recommended
|
fully configured and ready to serve any kind of request. It is recommended
|
||||||
to issue a software reset of the switch during this setup function in order to
|
to issue a software reset of the switch during this setup function in order to
|
||||||
avoid relying on what a previous software agent such as a bootloader/firmware
|
avoid relying on what a previous software agent such as a bootloader/firmware
|
||||||
may have previously configured.
|
may have previously configured. The method responsible for undoing any
|
||||||
|
applicable allocations or operations done here is ``teardown``.
|
||||||
|
|
||||||
|
- ``port_setup`` and ``port_teardown``: methods for initialization and
|
||||||
|
destruction of per-port data structures. It is mandatory for some operations
|
||||||
|
such as registering and unregistering devlink port regions to be done from
|
||||||
|
these methods, otherwise they are optional. A port will be torn down only if
|
||||||
|
it has been previously set up. It is possible for a port to be set up during
|
||||||
|
probing only to be torn down immediately afterwards, for example in case its
|
||||||
|
PHY cannot be found. In this case, probing of the DSA switch continues
|
||||||
|
without that particular port.
|
||||||
|
|
||||||
PHY devices and link management
|
PHY devices and link management
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
@ -635,26 +727,198 @@ Power management
|
||||||
``BR_STATE_DISABLED`` and propagating changes to the hardware if this port is
|
``BR_STATE_DISABLED`` and propagating changes to the hardware if this port is
|
||||||
disabled while being a bridge member
|
disabled while being a bridge member
|
||||||
|
|
||||||
|
Address databases
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Switching hardware is expected to have a table for FDB entries, however not all
|
||||||
|
of them are active at the same time. An address database is the subset (partition)
|
||||||
|
of FDB entries that is active (can be matched by address learning on RX, or FDB
|
||||||
|
lookup on TX) depending on the state of the port. An address database may
|
||||||
|
occasionally be called "FID" (Filtering ID) in this document, although the
|
||||||
|
underlying implementation may choose whatever is available to the hardware.
|
||||||
|
|
||||||
|
For example, all ports that belong to a VLAN-unaware bridge (which is
|
||||||
|
*currently* VLAN-unaware) are expected to learn source addresses in the
|
||||||
|
database associated by the driver with that bridge (and not with other
|
||||||
|
VLAN-unaware bridges). During forwarding and FDB lookup, a packet received on a
|
||||||
|
VLAN-unaware bridge port should be able to find a VLAN-unaware FDB entry having
|
||||||
|
the same MAC DA as the packet, which is present on another port member of the
|
||||||
|
same bridge. At the same time, the FDB lookup process must be able to not find
|
||||||
|
an FDB entry having the same MAC DA as the packet, if that entry points towards
|
||||||
|
a port which is a member of a different VLAN-unaware bridge (and is therefore
|
||||||
|
associated with a different address database).
|
||||||
|
|
||||||
|
Similarly, each VLAN of each offloaded VLAN-aware bridge should have an
|
||||||
|
associated address database, which is shared by all ports which are members of
|
||||||
|
that VLAN, but not shared by ports belonging to different bridges that are
|
||||||
|
members of the same VID.
|
||||||
|
|
||||||
|
In this context, a VLAN-unaware database means that all packets are expected to
|
||||||
|
match on it irrespective of VLAN ID (only MAC address lookup), whereas a
|
||||||
|
VLAN-aware database means that packets are supposed to match based on the VLAN
|
||||||
|
ID from the classified 802.1Q header (or the pvid if untagged).
|
||||||
|
|
||||||
|
At the bridge layer, VLAN-unaware FDB entries have the special VID value of 0,
|
||||||
|
whereas VLAN-aware FDB entries have non-zero VID values. Note that a
|
||||||
|
VLAN-unaware bridge may have VLAN-aware (non-zero VID) FDB entries, and a
|
||||||
|
VLAN-aware bridge may have VLAN-unaware FDB entries. As in hardware, the
|
||||||
|
software bridge keeps separate address databases, and offloads to hardware the
|
||||||
|
FDB entries belonging to these databases, through switchdev, asynchronously
|
||||||
|
relative to the moment when the databases become active or inactive.
|
||||||
|
|
||||||
|
When a user port operates in standalone mode, its driver should configure it to
|
||||||
|
use a separate database called a port private database. This is different from
|
||||||
|
the databases described above, and should impede operation as standalone port
|
||||||
|
(packet in, packet out to the CPU port) as little as possible. For example,
|
||||||
|
on ingress, it should not attempt to learn the MAC SA of ingress traffic, since
|
||||||
|
learning is a bridging layer service and this is a standalone port, therefore
|
||||||
|
it would consume useless space. With no address learning, the port private
|
||||||
|
database should be empty in a naive implementation, and in this case, all
|
||||||
|
received packets should be trivially flooded to the CPU port.
|
||||||
|
|
||||||
|
DSA (cascade) and CPU ports are also called "shared" ports because they service
|
||||||
|
multiple address databases, and the database that a packet should be associated
|
||||||
|
to is usually embedded in the DSA tag. This means that the CPU port may
|
||||||
|
simultaneously transport packets coming from a standalone port (which were
|
||||||
|
classified by hardware in one address database), and from a bridge port (which
|
||||||
|
were classified to a different address database).
|
||||||
|
|
||||||
|
Switch drivers which satisfy certain criteria are able to optimize the naive
|
||||||
|
configuration by removing the CPU port from the flooding domain of the switch,
|
||||||
|
and just program the hardware with FDB entries pointing towards the CPU port
|
||||||
|
for which it is known that software is interested in those MAC addresses.
|
||||||
|
Packets which do not match a known FDB entry will not be delivered to the CPU,
|
||||||
|
which will save CPU cycles required for creating an skb just to drop it.
|
||||||
|
|
||||||
|
DSA is able to perform host address filtering for the following kinds of
|
||||||
|
addresses:
|
||||||
|
|
||||||
|
- Primary unicast MAC addresses of ports (``dev->dev_addr``). These are
|
||||||
|
associated with the port private database of the respective user port,
|
||||||
|
and the driver is notified to install them through ``port_fdb_add`` towards
|
||||||
|
the CPU port.
|
||||||
|
|
||||||
|
- Secondary unicast and multicast MAC addresses of ports (addresses added
|
||||||
|
through ``dev_uc_add()`` and ``dev_mc_add()``). These are also associated
|
||||||
|
with the port private database of the respective user port.
|
||||||
|
|
||||||
|
- Local/permanent bridge FDB entries (``BR_FDB_LOCAL``). These are the MAC
|
||||||
|
addresses of the bridge ports, for which packets must be terminated locally
|
||||||
|
and not forwarded. They are associated with the address database for that
|
||||||
|
bridge.
|
||||||
|
|
||||||
|
- Static bridge FDB entries installed towards foreign (non-DSA) interfaces
|
||||||
|
present in the same bridge as some DSA switch ports. These are also
|
||||||
|
associated with the address database for that bridge.
|
||||||
|
|
||||||
|
- Dynamically learned FDB entries on foreign interfaces present in the same
|
||||||
|
bridge as some DSA switch ports, only if ``ds->assisted_learning_on_cpu_port``
|
||||||
|
is set to true by the driver. These are associated with the address database
|
||||||
|
for that bridge.
|
||||||
|
|
||||||
|
For various operations detailed below, DSA provides a ``dsa_db`` structure
|
||||||
|
which can be of the following types:
|
||||||
|
|
||||||
|
- ``DSA_DB_PORT``: the FDB (or MDB) entry to be installed or deleted belongs to
|
||||||
|
the port private database of user port ``db->dp``.
|
||||||
|
- ``DSA_DB_BRIDGE``: the entry belongs to one of the address databases of bridge
|
||||||
|
``db->bridge``. Separation between the VLAN-unaware database and the per-VID
|
||||||
|
databases of this bridge is expected to be done by the driver.
|
||||||
|
- ``DSA_DB_LAG``: the entry belongs to the address database of LAG ``db->lag``.
|
||||||
|
Note: ``DSA_DB_LAG`` is currently unused and may be removed in the future.
|
||||||
|
|
||||||
|
The drivers which act upon the ``dsa_db`` argument in ``port_fdb_add``,
|
||||||
|
``port_mdb_add`` etc should declare ``ds->fdb_isolation`` as true.
|
||||||
|
|
||||||
|
DSA associates each offloaded bridge and each offloaded LAG with a one-based ID
|
||||||
|
(``struct dsa_bridge :: num``, ``struct dsa_lag :: id``) for the purposes of
|
||||||
|
refcounting addresses on shared ports. Drivers may piggyback on DSA's numbering
|
||||||
|
scheme (the ID is readable through ``db->bridge.num`` and ``db->lag.id`` or may
|
||||||
|
implement their own.
|
||||||
|
|
||||||
|
Only the drivers which declare support for FDB isolation are notified of FDB
|
||||||
|
entries on the CPU port belonging to ``DSA_DB_PORT`` databases.
|
||||||
|
For compatibility/legacy reasons, ``DSA_DB_BRIDGE`` addresses are notified to
|
||||||
|
drivers even if they do not support FDB isolation. However, ``db->bridge.num``
|
||||||
|
and ``db->lag.id`` are always set to 0 in that case (to denote the lack of
|
||||||
|
isolation, for refcounting purposes).
|
||||||
|
|
||||||
|
Note that it is not mandatory for a switch driver to implement physically
|
||||||
|
separate address databases for each standalone user port. Since FDB entries in
|
||||||
|
the port private databases will always point to the CPU port, there is no risk
|
||||||
|
for incorrect forwarding decisions. In this case, all standalone ports may
|
||||||
|
share the same database, but the reference counting of host-filtered addresses
|
||||||
|
(not deleting the FDB entry for a port's MAC address if it's still in use by
|
||||||
|
another port) becomes the responsibility of the driver, because DSA is unaware
|
||||||
|
that the port databases are in fact shared. This can be achieved by calling
|
||||||
|
``dsa_fdb_present_in_other_db()`` and ``dsa_mdb_present_in_other_db()``.
|
||||||
|
The down side is that the RX filtering lists of each user port are in fact
|
||||||
|
shared, which means that user port A may accept a packet with a MAC DA it
|
||||||
|
shouldn't have, only because that MAC address was in the RX filtering list of
|
||||||
|
user port B. These packets will still be dropped in software, however.
|
||||||
|
|
||||||
Bridge layer
|
Bridge layer
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
Offloading the bridge forwarding plane is optional and handled by the methods
|
||||||
|
below. They may be absent, return -EOPNOTSUPP, or ``ds->max_num_bridges`` may
|
||||||
|
be non-zero and exceeded, and in this case, joining a bridge port is still
|
||||||
|
possible, but the packet forwarding will take place in software, and the ports
|
||||||
|
under a software bridge must remain configured in the same way as for
|
||||||
|
standalone operation, i.e. have all bridging service functions (address
|
||||||
|
learning etc) disabled, and send all received packets to the CPU port only.
|
||||||
|
|
||||||
|
Concretely, a port starts offloading the forwarding plane of a bridge once it
|
||||||
|
returns success to the ``port_bridge_join`` method, and stops doing so after
|
||||||
|
``port_bridge_leave`` has been called. Offloading the bridge means autonomously
|
||||||
|
learning FDB entries in accordance with the software bridge port's state, and
|
||||||
|
autonomously forwarding (or flooding) received packets without CPU intervention.
|
||||||
|
This is optional even when offloading a bridge port. Tagging protocol drivers
|
||||||
|
are expected to call ``dsa_default_offload_fwd_mark(skb)`` for packets which
|
||||||
|
have already been autonomously forwarded in the forwarding domain of the
|
||||||
|
ingress switch port. DSA, through ``dsa_port_devlink_setup()``, considers all
|
||||||
|
switch ports part of the same tree ID to be part of the same bridge forwarding
|
||||||
|
domain (capable of autonomous forwarding to each other).
|
||||||
|
|
||||||
|
Offloading the TX forwarding process of a bridge is a distinct concept from
|
||||||
|
simply offloading its forwarding plane, and refers to the ability of certain
|
||||||
|
driver and tag protocol combinations to transmit a single skb coming from the
|
||||||
|
bridge device's transmit function to potentially multiple egress ports (and
|
||||||
|
thereby avoid its cloning in software).
|
||||||
|
|
||||||
|
Packets for which the bridge requests this behavior are called data plane
|
||||||
|
packets and have ``skb->offload_fwd_mark`` set to true in the tag protocol
|
||||||
|
driver's ``xmit`` function. Data plane packets are subject to FDB lookup,
|
||||||
|
hardware learning on the CPU port, and do not override the port STP state.
|
||||||
|
Additionally, replication of data plane packets (multicast, flooding) is
|
||||||
|
handled in hardware and the bridge driver will transmit a single skb for each
|
||||||
|
packet that may or may not need replication.
|
||||||
|
|
||||||
|
When the TX forwarding offload is enabled, the tag protocol driver is
|
||||||
|
responsible to inject packets into the data plane of the hardware towards the
|
||||||
|
correct bridging domain (FID) that the port is a part of. The port may be
|
||||||
|
VLAN-unaware, and in this case the FID must be equal to the FID used by the
|
||||||
|
driver for its VLAN-unaware address database associated with that bridge.
|
||||||
|
Alternatively, the bridge may be VLAN-aware, and in that case, it is guaranteed
|
||||||
|
that the packet is also VLAN-tagged with the VLAN ID that the bridge processed
|
||||||
|
this packet in. It is the responsibility of the hardware to untag the VID on
|
||||||
|
the egress-untagged ports, or keep the tag on the egress-tagged ones.
|
||||||
|
|
||||||
- ``port_bridge_join``: bridge layer function invoked when a given switch port is
|
- ``port_bridge_join``: bridge layer function invoked when a given switch port is
|
||||||
added to a bridge, this function should do what's necessary at the switch
|
added to a bridge, this function should do what's necessary at the switch
|
||||||
level to permit the joining port to be added to the relevant logical
|
level to permit the joining port to be added to the relevant logical
|
||||||
domain for it to ingress/egress traffic with other members of the bridge.
|
domain for it to ingress/egress traffic with other members of the bridge.
|
||||||
|
By setting the ``tx_fwd_offload`` argument to true, the TX forwarding process
|
||||||
|
of this bridge is also offloaded.
|
||||||
|
|
||||||
- ``port_bridge_leave``: bridge layer function invoked when a given switch port is
|
- ``port_bridge_leave``: bridge layer function invoked when a given switch port is
|
||||||
removed from a bridge, this function should do what's necessary at the
|
removed from a bridge, this function should do what's necessary at the
|
||||||
switch level to deny the leaving port from ingress/egress traffic from the
|
switch level to deny the leaving port from ingress/egress traffic from the
|
||||||
remaining bridge members. When the port leaves the bridge, it should be aged
|
remaining bridge members.
|
||||||
out at the switch hardware for the switch to (re) learn MAC addresses behind
|
|
||||||
this port.
|
|
||||||
|
|
||||||
- ``port_stp_state_set``: bridge layer function invoked when a given switch port STP
|
- ``port_stp_state_set``: bridge layer function invoked when a given switch port STP
|
||||||
state is computed by the bridge layer and should be propagated to switch
|
state is computed by the bridge layer and should be propagated to switch
|
||||||
hardware to forward/block/learn traffic. The switch driver is responsible for
|
hardware to forward/block/learn traffic.
|
||||||
computing a STP state change based on current and asked parameters and perform
|
|
||||||
the relevant ageing based on the intersection results
|
|
||||||
|
|
||||||
- ``port_bridge_flags``: bridge layer function invoked when a port must
|
- ``port_bridge_flags``: bridge layer function invoked when a port must
|
||||||
configure its settings for e.g. flooding of unknown traffic or source address
|
configure its settings for e.g. flooding of unknown traffic or source address
|
||||||
|
|
@ -667,21 +931,11 @@ Bridge layer
|
||||||
CPU port, and flooding towards the CPU port should also be enabled, due to a
|
CPU port, and flooding towards the CPU port should also be enabled, due to a
|
||||||
lack of an explicit address filtering mechanism in the DSA core.
|
lack of an explicit address filtering mechanism in the DSA core.
|
||||||
|
|
||||||
- ``port_bridge_tx_fwd_offload``: bridge layer function invoked after
|
- ``port_fast_age``: bridge layer function invoked when flushing the
|
||||||
``port_bridge_join`` when a driver sets ``ds->num_fwd_offloading_bridges`` to
|
dynamically learned FDB entries on the port is necessary. This is called when
|
||||||
a non-zero value. Returning success in this function activates the TX
|
transitioning from an STP state where learning should take place to an STP
|
||||||
forwarding offload bridge feature for this port, which enables the tagging
|
state where it shouldn't, or when leaving a bridge, or when address learning
|
||||||
protocol driver to inject data plane packets towards the bridging domain that
|
is turned off via ``port_bridge_flags``.
|
||||||
the port is a part of. Data plane packets are subject to FDB lookup, hardware
|
|
||||||
learning on the CPU port, and do not override the port STP state.
|
|
||||||
Additionally, replication of data plane packets (multicast, flooding) is
|
|
||||||
handled in hardware and the bridge driver will transmit a single skb for each
|
|
||||||
packet that needs replication. The method is provided as a configuration
|
|
||||||
point for drivers that need to configure the hardware for enabling this
|
|
||||||
feature.
|
|
||||||
|
|
||||||
- ``port_bridge_tx_fwd_unoffload``: bridge layer function invoked when a driver
|
|
||||||
leaves a bridge port which had the TX forwarding offload feature enabled.
|
|
||||||
|
|
||||||
Bridge VLAN filtering
|
Bridge VLAN filtering
|
||||||
---------------------
|
---------------------
|
||||||
|
|
@ -697,55 +951,44 @@ Bridge VLAN filtering
|
||||||
allowed.
|
allowed.
|
||||||
|
|
||||||
- ``port_vlan_add``: bridge layer function invoked when a VLAN is configured
|
- ``port_vlan_add``: bridge layer function invoked when a VLAN is configured
|
||||||
(tagged or untagged) for the given switch port. If the operation is not
|
(tagged or untagged) for the given switch port. The CPU port becomes a member
|
||||||
supported by the hardware, this function should return ``-EOPNOTSUPP`` to
|
of a VLAN only if a foreign bridge port is also a member of it (and
|
||||||
inform the bridge code to fallback to a software implementation.
|
forwarding needs to take place in software), or the VLAN is installed to the
|
||||||
|
VLAN group of the bridge device itself, for termination purposes
|
||||||
|
(``bridge vlan add dev br0 vid 100 self``). VLANs on shared ports are
|
||||||
|
reference counted and removed when there is no user left. Drivers do not need
|
||||||
|
to manually install a VLAN on the CPU port.
|
||||||
|
|
||||||
- ``port_vlan_del``: bridge layer function invoked when a VLAN is removed from the
|
- ``port_vlan_del``: bridge layer function invoked when a VLAN is removed from the
|
||||||
given switch port
|
given switch port
|
||||||
|
|
||||||
- ``port_vlan_dump``: bridge layer function invoked with a switchdev callback
|
|
||||||
function that the driver has to call for each VLAN the given port is a member
|
|
||||||
of. A switchdev object is used to carry the VID and bridge flags.
|
|
||||||
|
|
||||||
- ``port_fdb_add``: bridge layer function invoked when the bridge wants to install a
|
- ``port_fdb_add``: bridge layer function invoked when the bridge wants to install a
|
||||||
Forwarding Database entry, the switch hardware should be programmed with the
|
Forwarding Database entry, the switch hardware should be programmed with the
|
||||||
specified address in the specified VLAN Id in the forwarding database
|
specified address in the specified VLAN Id in the forwarding database
|
||||||
associated with this VLAN ID. If the operation is not supported, this
|
associated with this VLAN ID.
|
||||||
function should return ``-EOPNOTSUPP`` to inform the bridge code to fallback to
|
|
||||||
a software implementation.
|
|
||||||
|
|
||||||
.. note:: VLAN ID 0 corresponds to the port private database, which, in the context
|
|
||||||
of DSA, would be its port-based VLAN, used by the associated bridge device.
|
|
||||||
|
|
||||||
- ``port_fdb_del``: bridge layer function invoked when the bridge wants to remove a
|
- ``port_fdb_del``: bridge layer function invoked when the bridge wants to remove a
|
||||||
Forwarding Database entry, the switch hardware should be programmed to delete
|
Forwarding Database entry, the switch hardware should be programmed to delete
|
||||||
the specified MAC address from the specified VLAN ID if it was mapped into
|
the specified MAC address from the specified VLAN ID if it was mapped into
|
||||||
this port forwarding database
|
this port forwarding database
|
||||||
|
|
||||||
- ``port_fdb_dump``: bridge layer function invoked with a switchdev callback
|
- ``port_fdb_dump``: bridge bypass function invoked by ``ndo_fdb_dump`` on the
|
||||||
function that the driver has to call for each MAC address known to be behind
|
physical DSA port interfaces. Since DSA does not attempt to keep in sync its
|
||||||
the given port. A switchdev object is used to carry the VID and FDB info.
|
hardware FDB entries with the software bridge, this method is implemented as
|
||||||
|
a means to view the entries visible on user ports in the hardware database.
|
||||||
|
The entries reported by this function have the ``self`` flag in the output of
|
||||||
|
the ``bridge fdb show`` command.
|
||||||
|
|
||||||
- ``port_mdb_add``: bridge layer function invoked when the bridge wants to install
|
- ``port_mdb_add``: bridge layer function invoked when the bridge wants to install
|
||||||
a multicast database entry. If the operation is not supported, this function
|
a multicast database entry. The switch hardware should be programmed with the
|
||||||
should return ``-EOPNOTSUPP`` to inform the bridge code to fallback to a
|
|
||||||
software implementation. The switch hardware should be programmed with the
|
|
||||||
specified address in the specified VLAN ID in the forwarding database
|
specified address in the specified VLAN ID in the forwarding database
|
||||||
associated with this VLAN ID.
|
associated with this VLAN ID.
|
||||||
|
|
||||||
.. note:: VLAN ID 0 corresponds to the port private database, which, in the context
|
|
||||||
of DSA, would be its port-based VLAN, used by the associated bridge device.
|
|
||||||
|
|
||||||
- ``port_mdb_del``: bridge layer function invoked when the bridge wants to remove a
|
- ``port_mdb_del``: bridge layer function invoked when the bridge wants to remove a
|
||||||
multicast database entry, the switch hardware should be programmed to delete
|
multicast database entry, the switch hardware should be programmed to delete
|
||||||
the specified MAC address from the specified VLAN ID if it was mapped into
|
the specified MAC address from the specified VLAN ID if it was mapped into
|
||||||
this port forwarding database.
|
this port forwarding database.
|
||||||
|
|
||||||
- ``port_mdb_dump``: bridge layer function invoked with a switchdev callback
|
|
||||||
function that the driver has to call for each MAC address known to be behind
|
|
||||||
the given port. A switchdev object is used to carry the VID and MDB info.
|
|
||||||
|
|
||||||
Link aggregation
|
Link aggregation
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1052,11 +1052,7 @@ udp_rmem_min - INTEGER
|
||||||
Default: 4K
|
Default: 4K
|
||||||
|
|
||||||
udp_wmem_min - INTEGER
|
udp_wmem_min - INTEGER
|
||||||
Minimal size of send buffer used by UDP sockets in moderation.
|
UDP does not have tx memory accounting and this tunable has no effect.
|
||||||
Each UDP socket is able to use the size for sending data, even if
|
|
||||||
total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
|
|
||||||
|
|
||||||
Default: 4K
|
|
||||||
|
|
||||||
RAW variables
|
RAW variables
|
||||||
=============
|
=============
|
||||||
|
|
@ -1085,7 +1081,7 @@ cipso_cache_enable - BOOLEAN
|
||||||
cipso_cache_bucket_size - INTEGER
|
cipso_cache_bucket_size - INTEGER
|
||||||
The CIPSO label cache consists of a fixed size hash table with each
|
The CIPSO label cache consists of a fixed size hash table with each
|
||||||
hash bucket containing a number of cache entries. This variable limits
|
hash bucket containing a number of cache entries. This variable limits
|
||||||
the number of entries in each hash bucket; the larger the value the
|
the number of entries in each hash bucket; the larger the value is, the
|
||||||
more CIPSO label mappings that can be cached. When the number of
|
more CIPSO label mappings that can be cached. When the number of
|
||||||
entries in a given hash bucket reaches this limit adding new entries
|
entries in a given hash bucket reaches this limit adding new entries
|
||||||
causes the oldest entry in the bucket to be removed to make room.
|
causes the oldest entry in the bucket to be removed to make room.
|
||||||
|
|
@ -1179,7 +1175,7 @@ ip_autobind_reuse - BOOLEAN
|
||||||
option should only be set by experts.
|
option should only be set by experts.
|
||||||
Default: 0
|
Default: 0
|
||||||
|
|
||||||
ip_dynaddr - BOOLEAN
|
ip_dynaddr - INTEGER
|
||||||
If set non-zero, enables support for dynamic addresses.
|
If set non-zero, enables support for dynamic addresses.
|
||||||
If set to a non-zero value larger than 1, a kernel log
|
If set to a non-zero value larger than 1, a kernel log
|
||||||
message will be printed when dynamic address rewriting
|
message will be printed when dynamic address rewriting
|
||||||
|
|
@ -2870,7 +2866,14 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max
|
||||||
Default: 4K
|
Default: 4K
|
||||||
|
|
||||||
sctp_wmem - vector of 3 INTEGERs: min, default, max
|
sctp_wmem - vector of 3 INTEGERs: min, default, max
|
||||||
Currently this tunable has no effect.
|
Only the first value ("min") is used, "default" and "max" are
|
||||||
|
ignored.
|
||||||
|
|
||||||
|
min: Minimum size of send buffer that can be used by SCTP sockets.
|
||||||
|
It is guaranteed to each SCTP socket (but not association) even
|
||||||
|
under moderate memory pressure.
|
||||||
|
|
||||||
|
Default: 4K
|
||||||
|
|
||||||
addr_scope_policy - INTEGER
|
addr_scope_policy - INTEGER
|
||||||
Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00
|
Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ AC97
|
||||||
====
|
====
|
||||||
|
|
||||||
AC97 is a five wire interface commonly found on many PC sound cards. It is
|
AC97 is a five wire interface commonly found on many PC sound cards. It is
|
||||||
now also popular in many portable devices. This DAI has a reset line and time
|
now also popular in many portable devices. This DAI has a RESET line and time
|
||||||
multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines.
|
multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines.
|
||||||
The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the
|
The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the
|
||||||
frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
|
frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
|
||||||
|
|
|
||||||
|
|
@ -5657,7 +5657,8 @@ by a string of size ``name_size``.
|
||||||
#define KVM_STATS_UNIT_BYTES (0x1 << KVM_STATS_UNIT_SHIFT)
|
#define KVM_STATS_UNIT_BYTES (0x1 << KVM_STATS_UNIT_SHIFT)
|
||||||
#define KVM_STATS_UNIT_SECONDS (0x2 << KVM_STATS_UNIT_SHIFT)
|
#define KVM_STATS_UNIT_SECONDS (0x2 << KVM_STATS_UNIT_SHIFT)
|
||||||
#define KVM_STATS_UNIT_CYCLES (0x3 << KVM_STATS_UNIT_SHIFT)
|
#define KVM_STATS_UNIT_CYCLES (0x3 << KVM_STATS_UNIT_SHIFT)
|
||||||
#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_CYCLES
|
#define KVM_STATS_UNIT_BOOLEAN (0x4 << KVM_STATS_UNIT_SHIFT)
|
||||||
|
#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_BOOLEAN
|
||||||
|
|
||||||
#define KVM_STATS_BASE_SHIFT 8
|
#define KVM_STATS_BASE_SHIFT 8
|
||||||
#define KVM_STATS_BASE_MASK (0xF << KVM_STATS_BASE_SHIFT)
|
#define KVM_STATS_BASE_MASK (0xF << KVM_STATS_BASE_SHIFT)
|
||||||
|
|
@ -5702,14 +5703,13 @@ Bits 0-3 of ``flags`` encode the type:
|
||||||
by the ``hist_param`` field. The range of the Nth bucket (1 <= N < ``size``)
|
by the ``hist_param`` field. The range of the Nth bucket (1 <= N < ``size``)
|
||||||
is [``hist_param``*(N-1), ``hist_param``*N), while the range of the last
|
is [``hist_param``*(N-1), ``hist_param``*N), while the range of the last
|
||||||
bucket is [``hist_param``*(``size``-1), +INF). (+INF means positive infinity
|
bucket is [``hist_param``*(``size``-1), +INF). (+INF means positive infinity
|
||||||
value.) The bucket value indicates how many samples fell in the bucket's range.
|
value.)
|
||||||
* ``KVM_STATS_TYPE_LOG_HIST``
|
* ``KVM_STATS_TYPE_LOG_HIST``
|
||||||
The statistic is reported as a logarithmic histogram. The number of
|
The statistic is reported as a logarithmic histogram. The number of
|
||||||
buckets is specified by the ``size`` field. The range of the first bucket is
|
buckets is specified by the ``size`` field. The range of the first bucket is
|
||||||
[0, 1), while the range of the last bucket is [pow(2, ``size``-2), +INF).
|
[0, 1), while the range of the last bucket is [pow(2, ``size``-2), +INF).
|
||||||
Otherwise, The Nth bucket (1 < N < ``size``) covers
|
Otherwise, The Nth bucket (1 < N < ``size``) covers
|
||||||
[pow(2, N-2), pow(2, N-1)). The bucket value indicates how many samples fell
|
[pow(2, N-2), pow(2, N-1)).
|
||||||
in the bucket's range.
|
|
||||||
|
|
||||||
Bits 4-7 of ``flags`` encode the unit:
|
Bits 4-7 of ``flags`` encode the unit:
|
||||||
|
|
||||||
|
|
@ -5724,6 +5724,15 @@ Bits 4-7 of ``flags`` encode the unit:
|
||||||
It indicates that the statistics data is used to measure time or latency.
|
It indicates that the statistics data is used to measure time or latency.
|
||||||
* ``KVM_STATS_UNIT_CYCLES``
|
* ``KVM_STATS_UNIT_CYCLES``
|
||||||
It indicates that the statistics data is used to measure CPU clock cycles.
|
It indicates that the statistics data is used to measure CPU clock cycles.
|
||||||
|
* ``KVM_STATS_UNIT_BOOLEAN``
|
||||||
|
It indicates that the statistic will always be either 0 or 1. Boolean
|
||||||
|
statistics of "peak" type will never go back from 1 to 0. Boolean
|
||||||
|
statistics can be linear histograms (with two buckets) but not logarithmic
|
||||||
|
histograms.
|
||||||
|
|
||||||
|
Note that, in the case of histograms, the unit applies to the bucket
|
||||||
|
ranges, while the bucket value indicates how many samples fell in the
|
||||||
|
bucket's range.
|
||||||
|
|
||||||
Bits 8-11 of ``flags``, together with ``exponent``, encode the scale of the
|
Bits 8-11 of ``flags``, together with ``exponent``, encode the scale of the
|
||||||
unit:
|
unit:
|
||||||
|
|
@ -5746,7 +5755,7 @@ the corresponding statistics data.
|
||||||
|
|
||||||
The ``bucket_size`` field is used as a parameter for histogram statistics data.
|
The ``bucket_size`` field is used as a parameter for histogram statistics data.
|
||||||
It is only used by linear histogram statistics data, specifying the size of a
|
It is only used by linear histogram statistics data, specifying the size of a
|
||||||
bucket.
|
bucket in the unit expressed by bits 4-11 of ``flags`` together with ``exponent``.
|
||||||
|
|
||||||
The ``name`` field is the name string of the statistics data. The name string
|
The ``name`` field is the name string of the statistics data. The name string
|
||||||
starts at the end of ``struct kvm_stats_desc``. The maximum length including
|
starts at the end of ``struct kvm_stats_desc``. The maximum length including
|
||||||
|
|
|
||||||
17
MAINTAINERS
17
MAINTAINERS
|
|
@ -1038,6 +1038,7 @@ F: arch/arm64/boot/dts/amd/
|
||||||
|
|
||||||
AMD XGBE DRIVER
|
AMD XGBE DRIVER
|
||||||
M: Tom Lendacky <thomas.lendacky@amd.com>
|
M: Tom Lendacky <thomas.lendacky@amd.com>
|
||||||
|
M: "Shyam Sundar S K" <Shyam-sundar.S-k@amd.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
|
F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
|
||||||
|
|
@ -2497,10 +2498,8 @@ F: drivers/power/reset/oxnas-restart.c
|
||||||
N: oxnas
|
N: oxnas
|
||||||
|
|
||||||
ARM/PALM TREO SUPPORT
|
ARM/PALM TREO SUPPORT
|
||||||
M: Tomas Cech <sleep_walker@suse.com>
|
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Orphan
|
||||||
W: http://hackndev.com
|
|
||||||
F: arch/arm/mach-pxa/palmtreo.*
|
F: arch/arm/mach-pxa/palmtreo.*
|
||||||
|
|
||||||
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
|
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
|
||||||
|
|
@ -7486,6 +7485,8 @@ F: include/video/s1d13xxxfb.h
|
||||||
EROFS FILE SYSTEM
|
EROFS FILE SYSTEM
|
||||||
M: Gao Xiang <xiang@kernel.org>
|
M: Gao Xiang <xiang@kernel.org>
|
||||||
M: Chao Yu <chao@kernel.org>
|
M: Chao Yu <chao@kernel.org>
|
||||||
|
R: Yue Hu <huyue2@coolpad.com>
|
||||||
|
R: Jeffle Xu <jefflexu@linux.alibaba.com>
|
||||||
L: linux-erofs@lists.ozlabs.org
|
L: linux-erofs@lists.ozlabs.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
|
||||||
|
|
@ -14370,7 +14371,8 @@ S: Maintained
|
||||||
F: drivers/net/phy/nxp-c45-tja11xx.c
|
F: drivers/net/phy/nxp-c45-tja11xx.c
|
||||||
|
|
||||||
NXP FSPI DRIVER
|
NXP FSPI DRIVER
|
||||||
M: Ashish Kumar <ashish.kumar@nxp.com>
|
M: Han Xu <han.xu@nxp.com>
|
||||||
|
M: Haibo Chen <haibo.chen@nxp.com>
|
||||||
R: Yogesh Gaur <yogeshgaur.83@gmail.com>
|
R: Yogesh Gaur <yogeshgaur.83@gmail.com>
|
||||||
L: linux-spi@vger.kernel.org
|
L: linux-spi@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
@ -15856,7 +15858,7 @@ PIN CONTROLLER - FREESCALE
|
||||||
M: Dong Aisheng <aisheng.dong@nxp.com>
|
M: Dong Aisheng <aisheng.dong@nxp.com>
|
||||||
M: Fabio Estevam <festevam@gmail.com>
|
M: Fabio Estevam <festevam@gmail.com>
|
||||||
M: Shawn Guo <shawnguo@kernel.org>
|
M: Shawn Guo <shawnguo@kernel.org>
|
||||||
M: Stefan Agner <stefan@agner.ch>
|
M: Jacky Bai <ping.bai@nxp.com>
|
||||||
R: Pengutronix Kernel Team <kernel@pengutronix.de>
|
R: Pengutronix Kernel Team <kernel@pengutronix.de>
|
||||||
L: linux-gpio@vger.kernel.org
|
L: linux-gpio@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
@ -17280,12 +17282,15 @@ N: riscv
|
||||||
K: riscv
|
K: riscv
|
||||||
|
|
||||||
RISC-V/MICROCHIP POLARFIRE SOC SUPPORT
|
RISC-V/MICROCHIP POLARFIRE SOC SUPPORT
|
||||||
M: Lewis Hanly <lewis.hanly@microchip.com>
|
|
||||||
M: Conor Dooley <conor.dooley@microchip.com>
|
M: Conor Dooley <conor.dooley@microchip.com>
|
||||||
|
M: Daire McNamara <daire.mcnamara@microchip.com>
|
||||||
L: linux-riscv@lists.infradead.org
|
L: linux-riscv@lists.infradead.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: arch/riscv/boot/dts/microchip/
|
F: arch/riscv/boot/dts/microchip/
|
||||||
|
F: drivers/char/hw_random/mpfs-rng.c
|
||||||
|
F: drivers/clk/microchip/clk-mpfs.c
|
||||||
F: drivers/mailbox/mailbox-mpfs.c
|
F: drivers/mailbox/mailbox-mpfs.c
|
||||||
|
F: drivers/pci/controller/pcie-microchip-host.c
|
||||||
F: drivers/soc/microchip/
|
F: drivers/soc/microchip/
|
||||||
F: include/soc/microchip/mpfs.h
|
F: include/soc/microchip/mpfs.h
|
||||||
|
|
||||||
|
|
|
||||||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 19
|
PATCHLEVEL = 19
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc6
|
EXTRAVERSION =
|
||||||
NAME = Superb Owl
|
NAME = Superb Owl
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,13 @@ config MMU_GATHER_PAGE_SIZE
|
||||||
|
|
||||||
config MMU_GATHER_NO_RANGE
|
config MMU_GATHER_NO_RANGE
|
||||||
bool
|
bool
|
||||||
|
select MMU_GATHER_MERGE_VMAS
|
||||||
|
|
||||||
|
config MMU_GATHER_NO_FLUSH_CACHE
|
||||||
|
bool
|
||||||
|
|
||||||
|
config MMU_GATHER_MERGE_VMAS
|
||||||
|
bool
|
||||||
|
|
||||||
config MMU_GATHER_NO_GATHER
|
config MMU_GATHER_NO_GATHER
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ gpio8: gpio@28 {
|
||||||
reg = <0x28>;
|
reg = <0x28>;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
ngpio = <32>;
|
ngpios = <62>;
|
||||||
};
|
};
|
||||||
|
|
||||||
sgtl5000: codec@a {
|
sgtl5000: codec@a {
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ &i2c1 {
|
||||||
atmel_mxt_ts: touchscreen@4a {
|
atmel_mxt_ts: touchscreen@4a {
|
||||||
compatible = "atmel,maxtouch";
|
compatible = "atmel,maxtouch";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pinctrl_atmel_conn>;
|
pinctrl-0 = <&pinctrl_atmel_conn &pinctrl_atmel_snvs_conn>;
|
||||||
reg = <0x4a>;
|
reg = <0x4a>;
|
||||||
interrupt-parent = <&gpio5>;
|
interrupt-parent = <&gpio5>;
|
||||||
interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 / INT */
|
interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 107 / INT */
|
||||||
|
|
@ -331,7 +331,6 @@ MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0xb0a0 /* SODIMM 30 */
|
||||||
pinctrl_atmel_conn: atmelconngrp {
|
pinctrl_atmel_conn: atmelconngrp {
|
||||||
fsl,pins = <
|
fsl,pins = <
|
||||||
MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0xb0a0 /* SODIMM 106 */
|
MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0xb0a0 /* SODIMM 106 */
|
||||||
MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0xb0a0 /* SODIMM 107 */
|
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -684,6 +683,12 @@ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
|
||||||
};
|
};
|
||||||
|
|
||||||
&iomuxc_snvs {
|
&iomuxc_snvs {
|
||||||
|
pinctrl_atmel_snvs_conn: atmelsnvsconngrp {
|
||||||
|
fsl,pins = <
|
||||||
|
MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0xb0a0 /* SODIMM 107 */
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
pinctrl_snvs_gpio1: snvsgpio1grp {
|
pinctrl_snvs_gpio1: snvsgpio1grp {
|
||||||
fsl,pins = <
|
fsl,pins = <
|
||||||
MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x110a0 /* SODIMM 93 */
|
MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x110a0 /* SODIMM 93 */
|
||||||
|
|
|
||||||
|
|
@ -87,22 +87,22 @@ &mdio0 {
|
||||||
|
|
||||||
phy4: ethernet-phy@5 {
|
phy4: ethernet-phy@5 {
|
||||||
reg = <5>;
|
reg = <5>;
|
||||||
coma-mode-gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
|
coma-mode-gpios = <&gpio 37 GPIO_OPEN_DRAIN>;
|
||||||
};
|
};
|
||||||
|
|
||||||
phy5: ethernet-phy@6 {
|
phy5: ethernet-phy@6 {
|
||||||
reg = <6>;
|
reg = <6>;
|
||||||
coma-mode-gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
|
coma-mode-gpios = <&gpio 37 GPIO_OPEN_DRAIN>;
|
||||||
};
|
};
|
||||||
|
|
||||||
phy6: ethernet-phy@7 {
|
phy6: ethernet-phy@7 {
|
||||||
reg = <7>;
|
reg = <7>;
|
||||||
coma-mode-gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
|
coma-mode-gpios = <&gpio 37 GPIO_OPEN_DRAIN>;
|
||||||
};
|
};
|
||||||
|
|
||||||
phy7: ethernet-phy@8 {
|
phy7: ethernet-phy@8 {
|
||||||
reg = <8>;
|
reg = <8>;
|
||||||
coma-mode-gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
|
coma-mode-gpios = <&gpio 37 GPIO_OPEN_DRAIN>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ clocks {
|
||||||
sys_clk: sys_clk {
|
sys_clk: sys_clk {
|
||||||
compatible = "fixed-clock";
|
compatible = "fixed-clock";
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
clock-frequency = <162500000>;
|
clock-frequency = <165625000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
cpu_clk: cpu_clk {
|
cpu_clk: cpu_clk {
|
||||||
|
|
|
||||||
|
|
@ -506,6 +506,8 @@ blsp1_uart2: serial@f991e000 {
|
||||||
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
|
clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
|
||||||
clock-names = "core", "iface";
|
clock-names = "core", "iface";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&blsp1_uart2_default>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -581,6 +583,9 @@ blsp2_uart1: serial@f995d000 {
|
||||||
interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
|
interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
|
||||||
clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
||||||
clock-names = "core", "iface";
|
clock-names = "core", "iface";
|
||||||
|
pinctrl-names = "default", "sleep";
|
||||||
|
pinctrl-0 = <&blsp2_uart1_default>;
|
||||||
|
pinctrl-1 = <&blsp2_uart1_sleep>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -599,6 +604,8 @@ blsp2_uart4: serial@f9960000 {
|
||||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clocks = <&gcc GCC_BLSP2_UART4_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
clocks = <&gcc GCC_BLSP2_UART4_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
||||||
clock-names = "core", "iface";
|
clock-names = "core", "iface";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&blsp2_uart4_default>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -639,6 +646,9 @@ blsp2_i2c6: i2c@f9968000 {
|
||||||
interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clocks = <&gcc GCC_BLSP2_QUP6_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
clocks = <&gcc GCC_BLSP2_QUP6_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
||||||
clock-names = "core", "iface";
|
clock-names = "core", "iface";
|
||||||
|
pinctrl-names = "default", "sleep";
|
||||||
|
pinctrl-0 = <&blsp2_i2c6_default>;
|
||||||
|
pinctrl-1 = <&blsp2_i2c6_sleep>;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
};
|
};
|
||||||
|
|
@ -1256,7 +1266,7 @@ cd {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
blsp1_uart2_active: blsp1-uart2-active {
|
blsp1_uart2_default: blsp1-uart2-default {
|
||||||
rx {
|
rx {
|
||||||
pins = "gpio5";
|
pins = "gpio5";
|
||||||
function = "blsp_uart2";
|
function = "blsp_uart2";
|
||||||
|
|
@ -1272,7 +1282,7 @@ tx {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
blsp2_uart1_active: blsp2-uart1-active {
|
blsp2_uart1_default: blsp2-uart1-default {
|
||||||
tx-rts {
|
tx-rts {
|
||||||
pins = "gpio41", "gpio44";
|
pins = "gpio41", "gpio44";
|
||||||
function = "blsp_uart7";
|
function = "blsp_uart7";
|
||||||
|
|
@ -1295,7 +1305,7 @@ blsp2_uart1_sleep: blsp2-uart1-sleep {
|
||||||
bias-pull-down;
|
bias-pull-down;
|
||||||
};
|
};
|
||||||
|
|
||||||
blsp2_uart4_active: blsp2-uart4-active {
|
blsp2_uart4_default: blsp2-uart4-default {
|
||||||
tx-rts {
|
tx-rts {
|
||||||
pins = "gpio53", "gpio56";
|
pins = "gpio53", "gpio56";
|
||||||
function = "blsp_uart10";
|
function = "blsp_uart10";
|
||||||
|
|
@ -1406,7 +1416,19 @@ blsp2_i2c5_sleep: blsp2-i2c5-sleep {
|
||||||
bias-pull-up;
|
bias-pull-up;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BLSP2_I2C6 info is missing - nobody uses it though? */
|
blsp2_i2c6_default: blsp2-i2c6-default {
|
||||||
|
pins = "gpio87", "gpio88";
|
||||||
|
function = "blsp_i2c12";
|
||||||
|
drive-strength = <2>;
|
||||||
|
bias-disable;
|
||||||
|
};
|
||||||
|
|
||||||
|
blsp2_i2c6_sleep: blsp2-i2c6-sleep {
|
||||||
|
pins = "gpio87", "gpio88";
|
||||||
|
function = "blsp_i2c12";
|
||||||
|
drive-strength = <2>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
|
||||||
spi8_default: spi8_default {
|
spi8_default: spi8_default {
|
||||||
mosi {
|
mosi {
|
||||||
|
|
|
||||||
|
|
@ -1124,7 +1124,7 @@ AT91_XDMAC_DT_PERID(33))>,
|
||||||
clocks = <&pmc PMC_TYPE_PERIPHERAL 55>, <&pmc PMC_TYPE_GCK 55>;
|
clocks = <&pmc PMC_TYPE_PERIPHERAL 55>, <&pmc PMC_TYPE_GCK 55>;
|
||||||
clock-names = "pclk", "gclk";
|
clock-names = "pclk", "gclk";
|
||||||
assigned-clocks = <&pmc PMC_TYPE_CORE PMC_I2S1_MUX>;
|
assigned-clocks = <&pmc PMC_TYPE_CORE PMC_I2S1_MUX>;
|
||||||
assigned-parrents = <&pmc PMC_TYPE_GCK 55>;
|
assigned-clock-parents = <&pmc PMC_TYPE_GCK 55>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ &spi0 {
|
||||||
flash@0 {
|
flash@0 {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
compatible = "mxicy,mx25l1606e", "winbond,w25q128";
|
compatible = "mxicy,mx25l1606e", "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <40000000>;
|
spi-max-frequency = <40000000>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#else
|
#else
|
||||||
#define MAX_DMA_ADDRESS ({ \
|
#define MAX_DMA_ADDRESS ({ \
|
||||||
extern phys_addr_t arm_dma_zone_size; \
|
extern phys_addr_t arm_dma_zone_size; \
|
||||||
arm_dma_zone_size && arm_dma_zone_size < (0x10000000 - PAGE_OFFSET) ? \
|
arm_dma_zone_size && arm_dma_zone_size < (0x100000000ULL - PAGE_OFFSET) ? \
|
||||||
(PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
|
(PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,19 +112,6 @@ static __always_inline void set_domain(unsigned int val)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_USE_DOMAINS
|
|
||||||
#define modify_domain(dom,type) \
|
|
||||||
do { \
|
|
||||||
unsigned int domain = get_domain(); \
|
|
||||||
domain &= ~domain_mask(dom); \
|
|
||||||
domain = domain | domain_val(dom, type); \
|
|
||||||
set_domain(domain); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
static inline void modify_domain(unsigned dom, unsigned type) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate the T (user) versions of the LDR/STR and related
|
* Generate the T (user) versions of the LDR/STR and related
|
||||||
* instructions (inline assembly)
|
* instructions (inline assembly)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ enum {
|
||||||
MT_HIGH_VECTORS,
|
MT_HIGH_VECTORS,
|
||||||
MT_MEMORY_RWX,
|
MT_MEMORY_RWX,
|
||||||
MT_MEMORY_RW,
|
MT_MEMORY_RW,
|
||||||
|
MT_MEMORY_RO,
|
||||||
MT_ROM,
|
MT_ROM,
|
||||||
MT_MEMORY_RWX_NONCACHED,
|
MT_MEMORY_RWX_NONCACHED,
|
||||||
MT_MEMORY_RW_DTCM,
|
MT_MEMORY_RW_DTCM,
|
||||||
|
|
|
||||||
|
|
@ -163,5 +163,31 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
|
||||||
((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
|
((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update ITSTATE after normal execution of an IT block instruction.
|
||||||
|
*
|
||||||
|
* The 8 IT state bits are split into two parts in CPSR:
|
||||||
|
* ITSTATE<1:0> are in CPSR<26:25>
|
||||||
|
* ITSTATE<7:2> are in CPSR<15:10>
|
||||||
|
*/
|
||||||
|
static inline unsigned long it_advance(unsigned long cpsr)
|
||||||
|
{
|
||||||
|
if ((cpsr & 0x06000400) == 0) {
|
||||||
|
/* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
|
||||||
|
cpsr &= ~PSR_IT_MASK;
|
||||||
|
} else {
|
||||||
|
/* We need to shift left ITSTATE<4:0> */
|
||||||
|
const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
|
||||||
|
unsigned long it = cpsr & mask;
|
||||||
|
it <<= 1;
|
||||||
|
it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
|
||||||
|
it &= mask;
|
||||||
|
cpsr &= ~mask;
|
||||||
|
cpsr |= it;
|
||||||
|
}
|
||||||
|
return cpsr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,7 @@ local_restart:
|
||||||
b ret_fast_syscall
|
b ret_fast_syscall
|
||||||
#endif
|
#endif
|
||||||
ENDPROC(vector_swi)
|
ENDPROC(vector_swi)
|
||||||
|
.ltorg
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the really slow path. We're going to be doing
|
* This is the really slow path. We're going to be doing
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ ENDPROC(_find_first_zero_bit_le)
|
||||||
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
||||||
*/
|
*/
|
||||||
ENTRY(_find_next_zero_bit_le)
|
ENTRY(_find_next_zero_bit_le)
|
||||||
teq r1, #0
|
cmp r2, r1
|
||||||
beq 3b
|
bhs 3b
|
||||||
ands ip, r2, #7
|
ands ip, r2, #7
|
||||||
beq 1b @ If new byte, goto old routine
|
beq 1b @ If new byte, goto old routine
|
||||||
ARM( ldrb r3, [r0, r2, lsr #3] )
|
ARM( ldrb r3, [r0, r2, lsr #3] )
|
||||||
|
|
@ -81,8 +81,8 @@ ENDPROC(_find_first_bit_le)
|
||||||
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
* Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
|
||||||
*/
|
*/
|
||||||
ENTRY(_find_next_bit_le)
|
ENTRY(_find_next_bit_le)
|
||||||
teq r1, #0
|
cmp r2, r1
|
||||||
beq 3b
|
bhs 3b
|
||||||
ands ip, r2, #7
|
ands ip, r2, #7
|
||||||
beq 1b @ If new byte, goto old routine
|
beq 1b @ If new byte, goto old routine
|
||||||
ARM( ldrb r3, [r0, r2, lsr #3] )
|
ARM( ldrb r3, [r0, r2, lsr #3] )
|
||||||
|
|
@ -115,8 +115,8 @@ ENTRY(_find_first_zero_bit_be)
|
||||||
ENDPROC(_find_first_zero_bit_be)
|
ENDPROC(_find_first_zero_bit_be)
|
||||||
|
|
||||||
ENTRY(_find_next_zero_bit_be)
|
ENTRY(_find_next_zero_bit_be)
|
||||||
teq r1, #0
|
cmp r2, r1
|
||||||
beq 3b
|
bhs 3b
|
||||||
ands ip, r2, #7
|
ands ip, r2, #7
|
||||||
beq 1b @ If new byte, goto old routine
|
beq 1b @ If new byte, goto old routine
|
||||||
eor r3, r2, #0x18 @ big endian byte ordering
|
eor r3, r2, #0x18 @ big endian byte ordering
|
||||||
|
|
@ -149,8 +149,8 @@ ENTRY(_find_first_bit_be)
|
||||||
ENDPROC(_find_first_bit_be)
|
ENDPROC(_find_first_bit_be)
|
||||||
|
|
||||||
ENTRY(_find_next_bit_be)
|
ENTRY(_find_next_bit_be)
|
||||||
teq r1, #0
|
cmp r2, r1
|
||||||
beq 3b
|
bhs 3b
|
||||||
ands ip, r2, #7
|
ands ip, r2, #7
|
||||||
beq 1b @ If new byte, goto old routine
|
beq 1b @ If new byte, goto old routine
|
||||||
eor r3, r2, #0x18 @ big endian byte ordering
|
eor r3, r2, #0x18 @ big endian byte ordering
|
||||||
|
|
|
||||||
|
|
@ -549,7 +549,7 @@ static struct pxa2xx_spi_controller corgi_spi_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table corgi_spi_gpio_table = {
|
static struct gpiod_lookup_table corgi_spi_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.1",
|
.dev_id = "spi1",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
|
||||||
|
|
|
||||||
|
|
@ -635,7 +635,7 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
|
static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.2",
|
.dev_id = "spi2",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
{ },
|
{ },
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ struct platform_device pxa_spi_ssp4 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
|
static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.3",
|
.dev_id = "spi3",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
|
||||||
|
|
@ -149,7 +149,7 @@ static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
|
static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.4",
|
.dev_id = "spi4",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table littleton_spi_gpio_table = {
|
static struct gpiod_lookup_table littleton_spi_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.2",
|
.dev_id = "spi2",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
{ },
|
{ },
|
||||||
|
|
|
||||||
|
|
@ -994,7 +994,7 @@ static struct pxa2xx_spi_controller magician_spi_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table magician_spi_gpio_table = {
|
static struct gpiod_lookup_table magician_spi_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.2",
|
.dev_id = "spi2",
|
||||||
.table = {
|
.table = {
|
||||||
/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
|
/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
|
|
|
||||||
|
|
@ -578,7 +578,7 @@ static struct pxa2xx_spi_controller spitz_spi_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table spitz_spi_gpio_table = {
|
static struct gpiod_lookup_table spitz_spi_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.2",
|
.dev_id = "spi2",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
|
||||||
|
|
|
||||||
|
|
@ -623,7 +623,7 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
|
static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.1",
|
.dev_id = "spi1",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
{ },
|
{ },
|
||||||
|
|
@ -631,7 +631,7 @@ static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
|
static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
|
||||||
.dev_id = "pxa2xx-spi.2",
|
.dev_id = "spi2",
|
||||||
.table = {
|
.table = {
|
||||||
GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
|
||||||
{ },
|
{ },
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ void __init rockchip_suspend_init(void)
|
||||||
&match);
|
&match);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
pr_err("Failed to find PMU node\n");
|
pr_err("Failed to find PMU node\n");
|
||||||
return;
|
goto out_put;
|
||||||
}
|
}
|
||||||
pm_data = (struct rockchip_pm_data *) match->data;
|
pm_data = (struct rockchip_pm_data *) match->data;
|
||||||
|
|
||||||
|
|
@ -320,9 +320,12 @@ void __init rockchip_suspend_init(void)
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: matches init error %d\n", __func__, ret);
|
pr_err("%s: matches init error %d\n", __func__, ret);
|
||||||
return;
|
goto out_put;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend_set_ops(pm_data->ops);
|
suspend_set_ops(pm_data->ops);
|
||||||
|
|
||||||
|
out_put:
|
||||||
|
of_node_put(np);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -631,7 +631,11 @@ config CPU_USE_DOMAINS
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
This option enables or disables the use of domain switching
|
This option enables or disables the use of domain switching
|
||||||
via the set_fs() function.
|
using the DACR (domain access control register) to protect memory
|
||||||
|
domains from each other. In Linux we use three domains: kernel, user
|
||||||
|
and IO. The domains are used to protect userspace from kernelspace
|
||||||
|
and to handle IO-space as a special type of memory by assigning
|
||||||
|
manager or client roles to running code (such as a process).
|
||||||
|
|
||||||
config CPU_V7M_NUM_IRQ
|
config CPU_V7M_NUM_IRQ
|
||||||
int "Number of external interrupts connected to the NVIC"
|
int "Number of external interrupts connected to the NVIC"
|
||||||
|
|
|
||||||
|
|
@ -935,6 +935,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||||
if (type == TYPE_LDST)
|
if (type == TYPE_LDST)
|
||||||
do_alignment_finish_ldst(addr, instr, regs, offset);
|
do_alignment_finish_ldst(addr, instr, regs, offset);
|
||||||
|
|
||||||
|
if (thumb_mode(regs))
|
||||||
|
regs->ARM_cpsr = it_advance(regs->ARM_cpsr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bad_or_fault:
|
bad_or_fault:
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,13 @@ static struct mem_type mem_types[] __ro_after_init = {
|
||||||
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
|
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
|
||||||
.domain = DOMAIN_KERNEL,
|
.domain = DOMAIN_KERNEL,
|
||||||
},
|
},
|
||||||
|
[MT_MEMORY_RO] = {
|
||||||
|
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
|
||||||
|
L_PTE_XN | L_PTE_RDONLY,
|
||||||
|
.prot_l1 = PMD_TYPE_TABLE,
|
||||||
|
.prot_sect = PMD_TYPE_SECT,
|
||||||
|
.domain = DOMAIN_KERNEL,
|
||||||
|
},
|
||||||
[MT_ROM] = {
|
[MT_ROM] = {
|
||||||
.prot_sect = PMD_TYPE_SECT,
|
.prot_sect = PMD_TYPE_SECT,
|
||||||
.domain = DOMAIN_KERNEL,
|
.domain = DOMAIN_KERNEL,
|
||||||
|
|
@ -489,6 +496,7 @@ static void __init build_mem_type_table(void)
|
||||||
|
|
||||||
/* Also setup NX memory mapping */
|
/* Also setup NX memory mapping */
|
||||||
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
|
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_XN;
|
||||||
}
|
}
|
||||||
if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
|
if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
|
||||||
/*
|
/*
|
||||||
|
|
@ -568,6 +576,7 @@ static void __init build_mem_type_table(void)
|
||||||
mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||||
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||||
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -587,6 +596,8 @@ static void __init build_mem_type_table(void)
|
||||||
mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
|
mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
|
||||||
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
|
mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
|
||||||
mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
|
mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_S;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_pte |= L_PTE_SHARED;
|
||||||
mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
|
mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
|
||||||
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
|
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
|
||||||
mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
|
mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
|
||||||
|
|
@ -647,6 +658,8 @@ static void __init build_mem_type_table(void)
|
||||||
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
|
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
|
||||||
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
|
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
|
||||||
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
|
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_sect |= ecc_mask | cp->pmd;
|
||||||
|
mem_types[MT_MEMORY_RO].prot_pte |= kern_pgprot;
|
||||||
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
|
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
|
||||||
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
|
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
|
||||||
mem_types[MT_ROM].prot_sect |= cp->pmd;
|
mem_types[MT_ROM].prot_sect |= cp->pmd;
|
||||||
|
|
@ -1360,7 +1373,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
|
||||||
map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK);
|
map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK);
|
||||||
map.virtual = FDT_FIXED_BASE;
|
map.virtual = FDT_FIXED_BASE;
|
||||||
map.length = FDT_FIXED_SIZE;
|
map.length = FDT_FIXED_SIZE;
|
||||||
map.type = MT_ROM;
|
map.type = MT_MEMORY_RO;
|
||||||
create_mapping(&map);
|
create_mapping(&map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,7 @@ static unsigned int spectre_v2_install_workaround(unsigned int method)
|
||||||
#else
|
#else
|
||||||
static unsigned int spectre_v2_install_workaround(unsigned int method)
|
static unsigned int spectre_v2_install_workaround(unsigned int method)
|
||||||
{
|
{
|
||||||
pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n",
|
pr_info_once("Spectre V2: workarounds disabled by configuration\n");
|
||||||
smp_processor_id());
|
|
||||||
|
|
||||||
return SPECTRE_VULNERABLE;
|
return SPECTRE_VULNERABLE;
|
||||||
}
|
}
|
||||||
|
|
@ -209,10 +208,10 @@ static int spectre_bhb_install_workaround(int method)
|
||||||
return SPECTRE_VULNERABLE;
|
return SPECTRE_VULNERABLE;
|
||||||
|
|
||||||
spectre_bhb_method = method;
|
spectre_bhb_method = method;
|
||||||
}
|
|
||||||
|
|
||||||
pr_info("CPU%u: Spectre BHB: using %s workaround\n",
|
pr_info("CPU%u: Spectre BHB: enabling %s workaround for all CPUs\n",
|
||||||
smp_processor_id(), spectre_bhb_method_name(method));
|
smp_processor_id(), spectre_bhb_method_name(method));
|
||||||
|
}
|
||||||
|
|
||||||
return SPECTRE_MITIGATED;
|
return SPECTRE_MITIGATED;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
#include <asm/probes.h>
|
#include <asm/probes.h>
|
||||||
|
#include <asm/ptrace.h>
|
||||||
#include <asm/kprobes.h>
|
#include <asm/kprobes.h>
|
||||||
|
|
||||||
void __init arm_probes_decode_init(void);
|
void __init arm_probes_decode_init(void);
|
||||||
|
|
@ -35,31 +36,6 @@ void __init find_str_pc_offset(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update ITSTATE after normal execution of an IT block instruction.
|
|
||||||
*
|
|
||||||
* The 8 IT state bits are split into two parts in CPSR:
|
|
||||||
* ITSTATE<1:0> are in CPSR<26:25>
|
|
||||||
* ITSTATE<7:2> are in CPSR<15:10>
|
|
||||||
*/
|
|
||||||
static inline unsigned long it_advance(unsigned long cpsr)
|
|
||||||
{
|
|
||||||
if ((cpsr & 0x06000400) == 0) {
|
|
||||||
/* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
|
|
||||||
cpsr &= ~PSR_IT_MASK;
|
|
||||||
} else {
|
|
||||||
/* We need to shift left ITSTATE<4:0> */
|
|
||||||
const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
|
|
||||||
unsigned long it = cpsr & mask;
|
|
||||||
it <<= 1;
|
|
||||||
it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
|
|
||||||
it &= mask;
|
|
||||||
cpsr &= ~mask;
|
|
||||||
cpsr |= it;
|
|
||||||
}
|
|
||||||
return cpsr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
|
static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
long cpsr = regs->ARM_cpsr;
|
long cpsr = regs->ARM_cpsr;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@ cpus {
|
||||||
/delete-node/ cpu@3;
|
/delete-node/ cpu@3;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
timer {
|
||||||
|
compatible = "arm,armv8-timer";
|
||||||
|
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
|
||||||
|
};
|
||||||
|
|
||||||
pmu {
|
pmu {
|
||||||
compatible = "arm,cortex-a53-pmu";
|
compatible = "arm,cortex-a53-pmu";
|
||||||
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ cpu0: cpu@0 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "brcm,brahma-b53";
|
compatible = "brcm,brahma-b53";
|
||||||
reg = <0x0>;
|
reg = <0x0>;
|
||||||
|
enable-method = "spin-table";
|
||||||
|
cpu-release-addr = <0x0 0xfff8>;
|
||||||
next-level-cache = <&l2>;
|
next-level-cache = <&l2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,9 +224,12 @@ rst: syscon@1e60000 {
|
||||||
little-endian;
|
little-endian;
|
||||||
};
|
};
|
||||||
|
|
||||||
efuse@1e80000 {
|
sfp: efuse@1e80000 {
|
||||||
compatible = "fsl,ls1028a-sfp";
|
compatible = "fsl,ls1028a-sfp";
|
||||||
reg = <0x0 0x1e80000 0x0 0x10000>;
|
reg = <0x0 0x1e80000 0x0 0x10000>;
|
||||||
|
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
|
||||||
|
QORIQ_CLK_PLL_DIV(4)>;
|
||||||
|
clock-names = "sfp";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <1>;
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,8 @@ &cru {
|
||||||
<&cru ACLK_VIO>,
|
<&cru ACLK_VIO>,
|
||||||
<&cru ACLK_GIC_PRE>,
|
<&cru ACLK_GIC_PRE>,
|
||||||
<&cru PCLK_DDR>,
|
<&cru PCLK_DDR>,
|
||||||
<&cru ACLK_HDCP>;
|
<&cru ACLK_HDCP>,
|
||||||
|
<&cru ACLK_VDU>;
|
||||||
assigned-clock-rates =
|
assigned-clock-rates =
|
||||||
<600000000>, <1600000000>,
|
<600000000>, <1600000000>,
|
||||||
<1000000000>,
|
<1000000000>,
|
||||||
|
|
@ -388,6 +389,7 @@ &cru {
|
||||||
<400000000>,
|
<400000000>,
|
||||||
<200000000>,
|
<200000000>,
|
||||||
<200000000>,
|
<200000000>,
|
||||||
|
<400000000>,
|
||||||
<400000000>;
|
<400000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1462,7 +1462,8 @@ cru: clock-controller@ff760000 {
|
||||||
<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>,
|
<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>,
|
||||||
<&cru ACLK_VIO>, <&cru ACLK_HDCP>,
|
<&cru ACLK_VIO>, <&cru ACLK_HDCP>,
|
||||||
<&cru ACLK_GIC_PRE>,
|
<&cru ACLK_GIC_PRE>,
|
||||||
<&cru PCLK_DDR>;
|
<&cru PCLK_DDR>,
|
||||||
|
<&cru ACLK_VDU>;
|
||||||
assigned-clock-rates =
|
assigned-clock-rates =
|
||||||
<594000000>, <800000000>,
|
<594000000>, <800000000>,
|
||||||
<1000000000>,
|
<1000000000>,
|
||||||
|
|
@ -1473,7 +1474,8 @@ cru: clock-controller@ff760000 {
|
||||||
<100000000>, <50000000>,
|
<100000000>, <50000000>,
|
||||||
<400000000>, <400000000>,
|
<400000000>, <400000000>,
|
||||||
<200000000>,
|
<200000000>,
|
||||||
<200000000>;
|
<200000000>,
|
||||||
|
<400000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
grf: syscon@ff770000 {
|
grf: syscon@ff770000 {
|
||||||
|
|
|
||||||
|
|
@ -687,6 +687,7 @@ &usb_host1_ohci {
|
||||||
};
|
};
|
||||||
|
|
||||||
&usb_host0_xhci {
|
&usb_host0_xhci {
|
||||||
|
dr_mode = "host";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ &gmac1 {
|
||||||
assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>;
|
assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>;
|
||||||
assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>;
|
assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>;
|
||||||
clock_in_out = "input";
|
clock_in_out = "input";
|
||||||
phy-mode = "rgmii-id";
|
phy-mode = "rgmii";
|
||||||
phy-supply = <&vcc_3v3>;
|
phy-supply = <&vcc_3v3>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&gmac1m1_miim
|
pinctrl-0 = <&gmac1m1_miim
|
||||||
|
|
|
||||||
|
|
@ -389,9 +389,13 @@ CONFIG_SPMI=y
|
||||||
# CONFIG_PINCTRL_SUN8I_H3_R is not set
|
# CONFIG_PINCTRL_SUN8I_H3_R is not set
|
||||||
# CONFIG_PINCTRL_SUN50I_A64 is not set
|
# CONFIG_PINCTRL_SUN50I_A64 is not set
|
||||||
# CONFIG_PINCTRL_SUN50I_A64_R is not set
|
# CONFIG_PINCTRL_SUN50I_A64_R is not set
|
||||||
|
# CONFIG_PINCTRL_SUN50I_A100 is not set
|
||||||
|
# CONFIG_PINCTRL_SUN50I_A100_R is not set
|
||||||
# CONFIG_PINCTRL_SUN50I_H5 is not set
|
# CONFIG_PINCTRL_SUN50I_H5 is not set
|
||||||
# CONFIG_PINCTRL_SUN50I_H6 is not set
|
# CONFIG_PINCTRL_SUN50I_H6 is not set
|
||||||
# CONFIG_PINCTRL_SUN50I_H6_R is not set
|
# CONFIG_PINCTRL_SUN50I_H6_R is not set
|
||||||
|
# CONFIG_PINCTRL_SUN50I_H616 is not set
|
||||||
|
# CONFIG_PINCTRL_SUN50I_H616_R is not set
|
||||||
CONFIG_GPIO_GENERIC_PLATFORM=y
|
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||||
CONFIG_POWER_RESET_HISI=y
|
CONFIG_POWER_RESET_HISI=y
|
||||||
CONFIG_POWER_RESET_SYSCON=y
|
CONFIG_POWER_RESET_SYSCON=y
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,6 @@
|
||||||
#define __ASM_CSKY_TLB_H
|
#define __ASM_CSKY_TLB_H
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
#define tlb_start_vma(tlb, vma) \
|
|
||||||
do { \
|
|
||||||
if (!(tlb)->fullmm) \
|
|
||||||
flush_cache_range(vma, (vma)->vm_start, (vma)->vm_end); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define tlb_end_vma(tlb, vma) \
|
|
||||||
do { \
|
|
||||||
if (!(tlb)->fullmm) \
|
|
||||||
flush_tlb_range(vma, (vma)->vm_start, (vma)->vm_end); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
|
|
||||||
|
|
||||||
#include <asm-generic/tlb.h>
|
#include <asm-generic/tlb.h>
|
||||||
|
|
||||||
#endif /* __ASM_CSKY_TLB_H */
|
#endif /* __ASM_CSKY_TLB_H */
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,6 @@ config LOONGARCH
|
||||||
select GENERIC_TIME_VSYSCALL
|
select GENERIC_TIME_VSYSCALL
|
||||||
select GPIOLIB
|
select GPIOLIB
|
||||||
select HAVE_ARCH_AUDITSYSCALL
|
select HAVE_ARCH_AUDITSYSCALL
|
||||||
select HAVE_ARCH_COMPILER_H
|
|
||||||
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
select HAVE_ARCH_MMAP_RND_BITS if MMU
|
||||||
select HAVE_ARCH_SECCOMP_FILTER
|
select HAVE_ARCH_SECCOMP_FILTER
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
|
|
@ -108,6 +107,7 @@ config LOONGARCH
|
||||||
select TRACE_IRQFLAGS_SUPPORT
|
select TRACE_IRQFLAGS_SUPPORT
|
||||||
select USE_PERCPU_NUMA_NODE_ID
|
select USE_PERCPU_NUMA_NODE_ID
|
||||||
select ZONE_DMA32
|
select ZONE_DMA32
|
||||||
|
select MMU_GATHER_MERGE_VMAS if MMU
|
||||||
|
|
||||||
config 32BIT
|
config 32BIT
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -274,16 +274,4 @@
|
||||||
nor \dst, \src, zero
|
nor \dst, \src, zero
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro bgt r0 r1 label
|
|
||||||
blt \r1, \r0, \label
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro bltz r0 label
|
|
||||||
blt \r0, zero, \label
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro bgez r0 label
|
|
||||||
bge \r0, zero, \label
|
|
||||||
.endm
|
|
||||||
|
|
||||||
#endif /* _ASM_ASMMACRO_H */
|
#endif /* _ASM_ASMMACRO_H */
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/barrier.h>
|
#include <asm/barrier.h>
|
||||||
#include <asm/cmpxchg.h>
|
#include <asm/cmpxchg.h>
|
||||||
#include <asm/compiler.h>
|
|
||||||
|
|
||||||
#if __SIZEOF_LONG__ == 4
|
#if __SIZEOF_LONG__ == 4
|
||||||
#define __LL "ll.w "
|
#define __LL "ll.w "
|
||||||
|
|
@ -157,27 +156,25 @@ static inline int arch_atomic_sub_if_positive(int i, atomic_t *v)
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ll.w %1, %2 # atomic_sub_if_positive\n"
|
"1: ll.w %1, %2 # atomic_sub_if_positive\n"
|
||||||
" addi.w %0, %1, %3 \n"
|
" addi.w %0, %1, %3 \n"
|
||||||
" or %1, %0, $zero \n"
|
" move %1, %0 \n"
|
||||||
" blt %0, $zero, 2f \n"
|
" bltz %0, 2f \n"
|
||||||
" sc.w %1, %2 \n"
|
" sc.w %1, %2 \n"
|
||||||
" beq $zero, %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
__WEAK_LLSC_MB
|
__WEAK_LLSC_MB
|
||||||
: "=&r" (result), "=&r" (temp),
|
: "=&r" (result), "=&r" (temp), "+ZC" (v->counter)
|
||||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
|
||||||
: "I" (-i));
|
: "I" (-i));
|
||||||
} else {
|
} else {
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ll.w %1, %2 # atomic_sub_if_positive\n"
|
"1: ll.w %1, %2 # atomic_sub_if_positive\n"
|
||||||
" sub.w %0, %1, %3 \n"
|
" sub.w %0, %1, %3 \n"
|
||||||
" or %1, %0, $zero \n"
|
" move %1, %0 \n"
|
||||||
" blt %0, $zero, 2f \n"
|
" bltz %0, 2f \n"
|
||||||
" sc.w %1, %2 \n"
|
" sc.w %1, %2 \n"
|
||||||
" beq $zero, %1, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
__WEAK_LLSC_MB
|
__WEAK_LLSC_MB
|
||||||
: "=&r" (result), "=&r" (temp),
|
: "=&r" (result), "=&r" (temp), "+ZC" (v->counter)
|
||||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
|
||||||
: "r" (i));
|
: "r" (i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,27 +317,25 @@ static inline long arch_atomic64_sub_if_positive(long i, atomic64_t *v)
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ll.d %1, %2 # atomic64_sub_if_positive \n"
|
"1: ll.d %1, %2 # atomic64_sub_if_positive \n"
|
||||||
" addi.d %0, %1, %3 \n"
|
" addi.d %0, %1, %3 \n"
|
||||||
" or %1, %0, $zero \n"
|
" move %1, %0 \n"
|
||||||
" blt %0, $zero, 2f \n"
|
" bltz %0, 2f \n"
|
||||||
" sc.d %1, %2 \n"
|
" sc.d %1, %2 \n"
|
||||||
" beq %1, $zero, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
__WEAK_LLSC_MB
|
__WEAK_LLSC_MB
|
||||||
: "=&r" (result), "=&r" (temp),
|
: "=&r" (result), "=&r" (temp), "+ZC" (v->counter)
|
||||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
|
||||||
: "I" (-i));
|
: "I" (-i));
|
||||||
} else {
|
} else {
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ll.d %1, %2 # atomic64_sub_if_positive \n"
|
"1: ll.d %1, %2 # atomic64_sub_if_positive \n"
|
||||||
" sub.d %0, %1, %3 \n"
|
" sub.d %0, %1, %3 \n"
|
||||||
" or %1, %0, $zero \n"
|
" move %1, %0 \n"
|
||||||
" blt %0, $zero, 2f \n"
|
" bltz %0, 2f \n"
|
||||||
" sc.d %1, %2 \n"
|
" sc.d %1, %2 \n"
|
||||||
" beq %1, $zero, 1b \n"
|
" beqz %1, 1b \n"
|
||||||
"2: \n"
|
"2: \n"
|
||||||
__WEAK_LLSC_MB
|
__WEAK_LLSC_MB
|
||||||
: "=&r" (result), "=&r" (temp),
|
: "=&r" (result), "=&r" (temp), "+ZC" (v->counter)
|
||||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
|
||||||
: "r" (i));
|
: "r" (i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,9 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"sltu %0, %1, %2\n\t"
|
"sltu %0, %1, %2\n\t"
|
||||||
#if (__SIZEOF_LONG__ == 4)
|
#if (__SIZEOF_LONG__ == 4)
|
||||||
"sub.w %0, $r0, %0\n\t"
|
"sub.w %0, $zero, %0\n\t"
|
||||||
#elif (__SIZEOF_LONG__ == 8)
|
#elif (__SIZEOF_LONG__ == 8)
|
||||||
"sub.d %0, $r0, %0\n\t"
|
"sub.d %0, $zero, %0\n\t"
|
||||||
#endif
|
#endif
|
||||||
: "=r" (mask)
|
: "=r" (mask)
|
||||||
: "r" (index), "r" (size)
|
: "r" (index), "r" (size)
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"1: " ld " %0, %2 # __cmpxchg_asm \n" \
|
"1: " ld " %0, %2 # __cmpxchg_asm \n" \
|
||||||
" bne %0, %z3, 2f \n" \
|
" bne %0, %z3, 2f \n" \
|
||||||
" or $t0, %z4, $zero \n" \
|
" move $t0, %z4 \n" \
|
||||||
" " st " $t0, %1 \n" \
|
" " st " $t0, %1 \n" \
|
||||||
" beq $zero, $t0, 1b \n" \
|
" beqz $t0, 1b \n" \
|
||||||
"2: \n" \
|
"2: \n" \
|
||||||
__WEAK_LLSC_MB \
|
__WEAK_LLSC_MB \
|
||||||
: "=&r" (__ret), "=ZB"(*m) \
|
: "=&r" (__ret), "=ZB"(*m) \
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
||||||
*/
|
|
||||||
#ifndef _ASM_COMPILER_H
|
|
||||||
#define _ASM_COMPILER_H
|
|
||||||
|
|
||||||
#define GCC_OFF_SMALL_ASM() "ZC"
|
|
||||||
|
|
||||||
#define LOONGARCH_ISA_LEVEL "loongarch"
|
|
||||||
#define LOONGARCH_ISA_ARCH_LEVEL "arch=loongarch"
|
|
||||||
#define LOONGARCH_ISA_LEVEL_RAW loongarch
|
|
||||||
#define LOONGARCH_ISA_ARCH_LEVEL_RAW LOONGARCH_ISA_LEVEL_RAW
|
|
||||||
|
|
||||||
#endif /* _ASM_COMPILER_H */
|
|
||||||
|
|
@ -288,8 +288,6 @@ struct arch_elf_state {
|
||||||
.interp_fp_abi = LOONGARCH_ABI_FP_ANY, \
|
.interp_fp_abi = LOONGARCH_ABI_FP_ANY, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
|
|
||||||
|
|
||||||
extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
|
extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
|
||||||
bool is_interp, struct arch_elf_state *state);
|
bool is_interp, struct arch_elf_state *state);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include <linux/futex.h>
|
#include <linux/futex.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/barrier.h>
|
#include <asm/barrier.h>
|
||||||
#include <asm/compiler.h>
|
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
|
|
||||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
||||||
|
|
@ -17,7 +16,7 @@
|
||||||
"1: ll.w %1, %4 # __futex_atomic_op\n" \
|
"1: ll.w %1, %4 # __futex_atomic_op\n" \
|
||||||
" " insn " \n" \
|
" " insn " \n" \
|
||||||
"2: sc.w $t0, %2 \n" \
|
"2: sc.w $t0, %2 \n" \
|
||||||
" beq $t0, $zero, 1b \n" \
|
" beqz $t0, 1b \n" \
|
||||||
"3: \n" \
|
"3: \n" \
|
||||||
" .section .fixup,\"ax\" \n" \
|
" .section .fixup,\"ax\" \n" \
|
||||||
"4: li.w %0, %6 \n" \
|
"4: li.w %0, %6 \n" \
|
||||||
|
|
@ -82,9 +81,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newv
|
||||||
"# futex_atomic_cmpxchg_inatomic \n"
|
"# futex_atomic_cmpxchg_inatomic \n"
|
||||||
"1: ll.w %1, %3 \n"
|
"1: ll.w %1, %3 \n"
|
||||||
" bne %1, %z4, 3f \n"
|
" bne %1, %z4, 3f \n"
|
||||||
" or $t0, %z5, $zero \n"
|
" move $t0, %z5 \n"
|
||||||
"2: sc.w $t0, %2 \n"
|
"2: sc.w $t0, %2 \n"
|
||||||
" beq $zero, $t0, 1b \n"
|
" beqz $t0, 1b \n"
|
||||||
"3: \n"
|
"3: \n"
|
||||||
__WEAK_LLSC_MB
|
__WEAK_LLSC_MB
|
||||||
" .section .fixup,\"ax\" \n"
|
" .section .fixup,\"ax\" \n"
|
||||||
|
|
@ -95,8 +94,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newv
|
||||||
" "__UA_ADDR "\t1b, 4b \n"
|
" "__UA_ADDR "\t1b, 4b \n"
|
||||||
" "__UA_ADDR "\t2b, 4b \n"
|
" "__UA_ADDR "\t2b, 4b \n"
|
||||||
" .previous \n"
|
" .previous \n"
|
||||||
: "+r" (ret), "=&r" (val), "=" GCC_OFF_SMALL_ASM() (*uaddr)
|
: "+r" (ret), "=&r" (val), "=ZC" (*uaddr)
|
||||||
: GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
|
: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval),
|
||||||
"i" (-EFAULT)
|
"i" (-EFAULT)
|
||||||
: "memory", "t0");
|
: "memory", "t0");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include <asm/compiler.h>
|
|
||||||
#include <asm/loongarch.h>
|
#include <asm/loongarch.h>
|
||||||
|
|
||||||
static inline void arch_local_irq_enable(void)
|
static inline void arch_local_irq_enable(void)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <asm/cmpxchg.h>
|
#include <asm/cmpxchg.h>
|
||||||
#include <asm/compiler.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
atomic_long_t a;
|
atomic_long_t a;
|
||||||
|
|
|
||||||
|
|
@ -39,18 +39,6 @@ extern const struct plat_smp_ops loongson3_smp_ops;
|
||||||
|
|
||||||
#define MAX_PACKAGES 16
|
#define MAX_PACKAGES 16
|
||||||
|
|
||||||
/* Chip Config register of each physical cpu package */
|
|
||||||
extern u64 loongson_chipcfg[MAX_PACKAGES];
|
|
||||||
#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id]))
|
|
||||||
|
|
||||||
/* Chip Temperature register of each physical cpu package */
|
|
||||||
extern u64 loongson_chiptemp[MAX_PACKAGES];
|
|
||||||
#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id]))
|
|
||||||
|
|
||||||
/* Freq Control register of each physical cpu package */
|
|
||||||
extern u64 loongson_freqctrl[MAX_PACKAGES];
|
|
||||||
#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id]))
|
|
||||||
|
|
||||||
#define xconf_readl(addr) readl(addr)
|
#define xconf_readl(addr) readl(addr)
|
||||||
#define xconf_readq(addr) readq(addr)
|
#define xconf_readq(addr) readq(addr)
|
||||||
|
|
||||||
|
|
@ -58,7 +46,7 @@ static inline void xconf_writel(u32 val, volatile void __iomem *addr)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
" st.w %[v], %[hw], 0 \n"
|
" st.w %[v], %[hw], 0 \n"
|
||||||
" ld.b $r0, %[hw], 0 \n"
|
" ld.b $zero, %[hw], 0 \n"
|
||||||
:
|
:
|
||||||
: [hw] "r" (addr), [v] "r" (val)
|
: [hw] "r" (addr), [v] "r" (val)
|
||||||
);
|
);
|
||||||
|
|
@ -68,7 +56,7 @@ static inline void xconf_writeq(u64 val64, volatile void __iomem *addr)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
" st.d %[v], %[hw], 0 \n"
|
" st.d %[v], %[hw], 0 \n"
|
||||||
" ld.b $r0, %[hw], 0 \n"
|
" ld.b $zero, %[hw], 0 \n"
|
||||||
:
|
:
|
||||||
: [hw] "r" (addr), [v] "r" (val64)
|
: [hw] "r" (addr), [v] "r" (val64)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@
|
||||||
static __always_inline void prepare_frametrace(struct pt_regs *regs)
|
static __always_inline void prepare_frametrace(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
/* Save $r1 */
|
/* Save $ra */
|
||||||
STORE_ONE_REG(1)
|
STORE_ONE_REG(1)
|
||||||
/* Use $r1 to save PC */
|
/* Use $ra to save PC */
|
||||||
"pcaddi $r1, 0\n\t"
|
"pcaddi $ra, 0\n\t"
|
||||||
STR_LONG_S " $r1, %0\n\t"
|
STR_LONG_S " $ra, %0\n\t"
|
||||||
/* Restore $r1 */
|
/* Restore $ra */
|
||||||
STR_LONG_L " $r1, %1, "STR_LONGSIZE"\n\t"
|
STR_LONG_L " $ra, %1, "STR_LONGSIZE"\n\t"
|
||||||
STORE_ONE_REG(2)
|
STORE_ONE_REG(2)
|
||||||
STORE_ONE_REG(3)
|
STORE_ONE_REG(3)
|
||||||
STORE_ONE_REG(4)
|
STORE_ONE_REG(4)
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,14 @@ struct thread_info {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How to get the thread information struct from C. */
|
/* How to get the thread information struct from C. */
|
||||||
register struct thread_info *__current_thread_info __asm__("$r2");
|
register struct thread_info *__current_thread_info __asm__("$tp");
|
||||||
|
|
||||||
static inline struct thread_info *current_thread_info(void)
|
static inline struct thread_info *current_thread_info(void)
|
||||||
{
|
{
|
||||||
return __current_thread_info;
|
return __current_thread_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
register unsigned long current_stack_pointer __asm__("$r3");
|
register unsigned long current_stack_pointer __asm__("$sp");
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,16 +137,6 @@ static inline void invtlb_all(u32 op, u32 info, u64 addr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* LoongArch doesn't need any special per-pte or per-vma handling, except
|
|
||||||
* we need to flush cache for area to be unmapped.
|
|
||||||
*/
|
|
||||||
#define tlb_start_vma(tlb, vma) \
|
|
||||||
do { \
|
|
||||||
if (!(tlb)->fullmm) \
|
|
||||||
flush_cache_range(vma, vma->vm_start, vma->vm_end); \
|
|
||||||
} while (0)
|
|
||||||
#define tlb_end_vma(tlb, vma) do { } while (0)
|
|
||||||
#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
|
#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
|
||||||
|
|
||||||
static void tlb_flush(struct mmu_gather *tlb);
|
static void tlb_flush(struct mmu_gather *tlb);
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ do { \
|
||||||
"2: \n" \
|
"2: \n" \
|
||||||
" .section .fixup,\"ax\" \n" \
|
" .section .fixup,\"ax\" \n" \
|
||||||
"3: li.w %0, %3 \n" \
|
"3: li.w %0, %3 \n" \
|
||||||
" or %1, $r0, $r0 \n" \
|
" move %1, $zero \n" \
|
||||||
" b 2b \n" \
|
" b 2b \n" \
|
||||||
" .previous \n" \
|
" .previous \n" \
|
||||||
" .section __ex_table,\"a\" \n" \
|
" .section __ex_table,\"a\" \n" \
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,9 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||||
*/
|
*/
|
||||||
#include <asm/cpu-info.h>
|
|
||||||
#include <linux/cacheinfo.h>
|
#include <linux/cacheinfo.h>
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/cpu-info.h>
|
||||||
|
|
||||||
/* Populates leaf and increments to next leaf */
|
/* Populates leaf and increments to next leaf */
|
||||||
#define populate_cache(cache, leaf, c_level, c_type) \
|
#define populate_cache(cache, leaf, c_level, c_type) \
|
||||||
|
|
@ -17,6 +18,8 @@ do { \
|
||||||
leaf->ways_of_associativity = c->cache.ways; \
|
leaf->ways_of_associativity = c->cache.ways; \
|
||||||
leaf->size = c->cache.linesz * c->cache.sets * \
|
leaf->size = c->cache.linesz * c->cache.sets * \
|
||||||
c->cache.ways; \
|
c->cache.ways; \
|
||||||
|
if (leaf->level > 2) \
|
||||||
|
leaf->size *= nodes_per_package; \
|
||||||
leaf++; \
|
leaf++; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
@ -95,11 +98,15 @@ static void cache_cpumap_setup(unsigned int cpu)
|
||||||
|
|
||||||
int populate_cache_leaves(unsigned int cpu)
|
int populate_cache_leaves(unsigned int cpu)
|
||||||
{
|
{
|
||||||
int level = 1;
|
int level = 1, nodes_per_package = 1;
|
||||||
struct cpuinfo_loongarch *c = ¤t_cpu_data;
|
struct cpuinfo_loongarch *c = ¤t_cpu_data;
|
||||||
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
|
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
|
||||||
struct cacheinfo *this_leaf = this_cpu_ci->info_list;
|
struct cacheinfo *this_leaf = this_cpu_ci->info_list;
|
||||||
|
|
||||||
|
if (loongson_sysconf.nr_nodes > 1)
|
||||||
|
nodes_per_package = loongson_sysconf.cores_per_package
|
||||||
|
/ loongson_sysconf.cores_per_node;
|
||||||
|
|
||||||
if (c->icache.waysize) {
|
if (c->icache.waysize) {
|
||||||
populate_cache(dcache, this_leaf, level, CACHE_TYPE_DATA);
|
populate_cache(dcache, this_leaf, level, CACHE_TYPE_DATA);
|
||||||
populate_cache(icache, this_leaf, level++, CACHE_TYPE_INST);
|
populate_cache(icache, this_leaf, level++, CACHE_TYPE_INST);
|
||||||
|
|
|
||||||
|
|
@ -17,21 +17,6 @@ u64 efi_system_table;
|
||||||
struct loongson_system_configuration loongson_sysconf;
|
struct loongson_system_configuration loongson_sysconf;
|
||||||
EXPORT_SYMBOL(loongson_sysconf);
|
EXPORT_SYMBOL(loongson_sysconf);
|
||||||
|
|
||||||
u64 loongson_chipcfg[MAX_PACKAGES];
|
|
||||||
u64 loongson_chiptemp[MAX_PACKAGES];
|
|
||||||
u64 loongson_freqctrl[MAX_PACKAGES];
|
|
||||||
unsigned long long smp_group[MAX_PACKAGES];
|
|
||||||
|
|
||||||
static void __init register_addrs_set(u64 *registers, const u64 addr, int num)
|
|
||||||
{
|
|
||||||
u64 i;
|
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
*registers = (i << 44) | addr;
|
|
||||||
registers++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init init_environ(void)
|
void __init init_environ(void)
|
||||||
{
|
{
|
||||||
int efi_boot = fw_arg0;
|
int efi_boot = fw_arg0;
|
||||||
|
|
@ -50,11 +35,6 @@ void __init init_environ(void)
|
||||||
efi_memmap_init_early(&data);
|
efi_memmap_init_early(&data);
|
||||||
memblock_reserve(data.phys_map & PAGE_MASK,
|
memblock_reserve(data.phys_map & PAGE_MASK,
|
||||||
PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
|
PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
|
||||||
|
|
||||||
register_addrs_set(smp_group, TO_UNCACHE(0x1fe01000), 16);
|
|
||||||
register_addrs_set(loongson_chipcfg, TO_UNCACHE(0x1fe00180), 16);
|
|
||||||
register_addrs_set(loongson_chiptemp, TO_UNCACHE(0x1fe0019c), 16);
|
|
||||||
register_addrs_set(loongson_freqctrl, TO_UNCACHE(0x1fe001d0), 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init init_cpu_fullname(void)
|
static int __init init_cpu_fullname(void)
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ SYM_FUNC_START(_save_fp)
|
||||||
fpu_save_csr a0 t1
|
fpu_save_csr a0 t1
|
||||||
fpu_save_double a0 t1 # clobbers t1
|
fpu_save_double a0 t1 # clobbers t1
|
||||||
fpu_save_cc a0 t1 t2 # clobbers t1, t2
|
fpu_save_cc a0 t1 t2 # clobbers t1, t2
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(_save_fp)
|
SYM_FUNC_END(_save_fp)
|
||||||
EXPORT_SYMBOL(_save_fp)
|
EXPORT_SYMBOL(_save_fp)
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ SYM_FUNC_START(_restore_fp)
|
||||||
fpu_restore_double a0 t1 # clobbers t1
|
fpu_restore_double a0 t1 # clobbers t1
|
||||||
fpu_restore_csr a0 t1
|
fpu_restore_csr a0 t1
|
||||||
fpu_restore_cc a0 t1 t2 # clobbers t1, t2
|
fpu_restore_cc a0 t1 t2 # clobbers t1, t2
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(_restore_fp)
|
SYM_FUNC_END(_restore_fp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -216,7 +216,7 @@ SYM_FUNC_START(_init_fpu)
|
||||||
movgr2fr.d $f30, t1
|
movgr2fr.d $f30, t1
|
||||||
movgr2fr.d $f31, t1
|
movgr2fr.d $f31, t1
|
||||||
|
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(_init_fpu)
|
SYM_FUNC_END(_init_fpu)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -229,7 +229,7 @@ SYM_FUNC_START(_save_fp_context)
|
||||||
sc_save_fcsr a2 t1
|
sc_save_fcsr a2 t1
|
||||||
sc_save_fp a0
|
sc_save_fp a0
|
||||||
li.w a0, 0 # success
|
li.w a0, 0 # success
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(_save_fp_context)
|
SYM_FUNC_END(_save_fp_context)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -242,10 +242,10 @@ SYM_FUNC_START(_restore_fp_context)
|
||||||
sc_restore_fcc a1 t1 t2
|
sc_restore_fcc a1 t1 t2
|
||||||
sc_restore_fcsr a2 t1
|
sc_restore_fcsr a2 t1
|
||||||
li.w a0, 0 # success
|
li.w a0, 0 # success
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(_restore_fp_context)
|
SYM_FUNC_END(_restore_fp_context)
|
||||||
|
|
||||||
SYM_FUNC_START(fault)
|
SYM_FUNC_START(fault)
|
||||||
li.w a0, -EFAULT # failure
|
li.w a0, -EFAULT # failure
|
||||||
jirl zero, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(fault)
|
SYM_FUNC_END(fault)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ SYM_FUNC_START(__arch_cpu_idle)
|
||||||
nop
|
nop
|
||||||
idle 0
|
idle 0
|
||||||
/* end of rollback region */
|
/* end of rollback region */
|
||||||
1: jirl zero, ra, 0
|
1: jr ra
|
||||||
SYM_FUNC_END(__arch_cpu_idle)
|
SYM_FUNC_END(__arch_cpu_idle)
|
||||||
|
|
||||||
SYM_FUNC_START(handle_vint)
|
SYM_FUNC_START(handle_vint)
|
||||||
|
|
@ -91,5 +91,5 @@ SYM_FUNC_END(except_vec_cex)
|
||||||
|
|
||||||
SYM_FUNC_START(handle_sys)
|
SYM_FUNC_START(handle_sys)
|
||||||
la.abs t0, handle_syscall
|
la.abs t0, handle_syscall
|
||||||
jirl zero, t0, 0
|
jr t0
|
||||||
SYM_FUNC_END(handle_sys)
|
SYM_FUNC_END(handle_sys)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ SYM_CODE_START(kernel_entry) # kernel entry point
|
||||||
/* We might not get launched at the address the kernel is linked to,
|
/* We might not get launched at the address the kernel is linked to,
|
||||||
so we jump there. */
|
so we jump there. */
|
||||||
la.abs t0, 0f
|
la.abs t0, 0f
|
||||||
jirl zero, t0, 0
|
jr t0
|
||||||
0:
|
0:
|
||||||
la t0, __bss_start # clear .bss
|
la t0, __bss_start # clear .bss
|
||||||
st.d zero, t0, 0
|
st.d zero, t0, 0
|
||||||
|
|
@ -50,7 +50,7 @@ SYM_CODE_START(kernel_entry) # kernel entry point
|
||||||
/* KSave3 used for percpu base, initialized as 0 */
|
/* KSave3 used for percpu base, initialized as 0 */
|
||||||
csrwr zero, PERCPU_BASE_KS
|
csrwr zero, PERCPU_BASE_KS
|
||||||
/* GPR21 used for percpu base (runtime), initialized as 0 */
|
/* GPR21 used for percpu base (runtime), initialized as 0 */
|
||||||
or u0, zero, zero
|
move u0, zero
|
||||||
|
|
||||||
la tp, init_thread_union
|
la tp, init_thread_union
|
||||||
/* Set the SP after an empty pt_regs. */
|
/* Set the SP after an empty pt_regs. */
|
||||||
|
|
@ -86,7 +86,7 @@ SYM_CODE_START(smpboot_entry)
|
||||||
ld.d tp, t0, CPU_BOOT_TINFO
|
ld.d tp, t0, CPU_BOOT_TINFO
|
||||||
|
|
||||||
la.abs t0, 0f
|
la.abs t0, 0f
|
||||||
jirl zero, t0, 0
|
jr t0
|
||||||
0:
|
0:
|
||||||
bl start_secondary
|
bl start_secondary
|
||||||
SYM_CODE_END(smpboot_entry)
|
SYM_CODE_END(smpboot_entry)
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ static int fpr_set(struct task_struct *target,
|
||||||
const void *kbuf, const void __user *ubuf)
|
const void *kbuf, const void __user *ubuf)
|
||||||
{
|
{
|
||||||
const int fcc_start = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
const int fcc_start = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||||
const int fcc_end = fcc_start + sizeof(u64);
|
const int fcsr_start = fcc_start + sizeof(u64);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
BUG_ON(count % sizeof(elf_fpreg_t));
|
BUG_ON(count % sizeof(elf_fpreg_t));
|
||||||
|
|
@ -209,10 +209,12 @@ static int fpr_set(struct task_struct *target,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
&target->thread.fpu.fcc,
|
&target->thread.fpu.fcc, fcc_start,
|
||||||
fcc_start, fcc_end);
|
fcc_start + sizeof(u64));
|
||||||
|
err |= user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||||
|
&target->thread.fpu.fcsr, fcsr_start,
|
||||||
|
fcsr_start + sizeof(u32));
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
|
|
||||||
#include <acpi/reboot.h>
|
#include <acpi/reboot.h>
|
||||||
#include <asm/compiler.h>
|
|
||||||
#include <asm/idle.h>
|
#include <asm/idle.h>
|
||||||
#include <asm/loongarch.h>
|
#include <asm/loongarch.h>
|
||||||
#include <asm/reboot.h>
|
#include <asm/reboot.h>
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ static void __init parse_bios_table(const struct dmi_header *dm)
|
||||||
char *dmi_data = (char *)dm;
|
char *dmi_data = (char *)dm;
|
||||||
|
|
||||||
bios_extern = *(dmi_data + SMBIOS_BIOSEXTERN_OFFSET);
|
bios_extern = *(dmi_data + SMBIOS_BIOSEXTERN_OFFSET);
|
||||||
b_info.bios_size = *(dmi_data + SMBIOS_BIOSSIZE_OFFSET);
|
b_info.bios_size = (*(dmi_data + SMBIOS_BIOSSIZE_OFFSET) + 1) << 6;
|
||||||
|
|
||||||
if (bios_extern & LOONGSON_EFI_ENABLE)
|
if (bios_extern & LOONGSON_EFI_ENABLE)
|
||||||
set_bit(EFI_BOOT, &efi.flags);
|
set_bit(EFI_BOOT, &efi.flags);
|
||||||
|
|
|
||||||
|
|
@ -278,116 +278,29 @@ void loongson3_cpu_die(unsigned int cpu)
|
||||||
mb();
|
mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void play_dead(void)
|
||||||
* The target CPU should go to XKPRANGE (uncached area) and flush
|
|
||||||
* ICache/DCache/VCache before the control CPU can safely disable its clock.
|
|
||||||
*/
|
|
||||||
static void loongson3_play_dead(int *state_addr)
|
|
||||||
{
|
{
|
||||||
register int val;
|
register uint64_t addr;
|
||||||
register void *addr;
|
|
||||||
register void (*init_fn)(void);
|
register void (*init_fn)(void);
|
||||||
|
|
||||||
__asm__ __volatile__(
|
idle_task_exit();
|
||||||
" li.d %[addr], 0x8000000000000000\n"
|
|
||||||
"1: cacop 0x8, %[addr], 0 \n" /* flush ICache */
|
|
||||||
" cacop 0x8, %[addr], 1 \n"
|
|
||||||
" cacop 0x8, %[addr], 2 \n"
|
|
||||||
" cacop 0x8, %[addr], 3 \n"
|
|
||||||
" cacop 0x9, %[addr], 0 \n" /* flush DCache */
|
|
||||||
" cacop 0x9, %[addr], 1 \n"
|
|
||||||
" cacop 0x9, %[addr], 2 \n"
|
|
||||||
" cacop 0x9, %[addr], 3 \n"
|
|
||||||
" addi.w %[sets], %[sets], -1 \n"
|
|
||||||
" addi.d %[addr], %[addr], 0x40 \n"
|
|
||||||
" bnez %[sets], 1b \n"
|
|
||||||
" li.d %[addr], 0x8000000000000000\n"
|
|
||||||
"2: cacop 0xa, %[addr], 0 \n" /* flush VCache */
|
|
||||||
" cacop 0xa, %[addr], 1 \n"
|
|
||||||
" cacop 0xa, %[addr], 2 \n"
|
|
||||||
" cacop 0xa, %[addr], 3 \n"
|
|
||||||
" cacop 0xa, %[addr], 4 \n"
|
|
||||||
" cacop 0xa, %[addr], 5 \n"
|
|
||||||
" cacop 0xa, %[addr], 6 \n"
|
|
||||||
" cacop 0xa, %[addr], 7 \n"
|
|
||||||
" cacop 0xa, %[addr], 8 \n"
|
|
||||||
" cacop 0xa, %[addr], 9 \n"
|
|
||||||
" cacop 0xa, %[addr], 10 \n"
|
|
||||||
" cacop 0xa, %[addr], 11 \n"
|
|
||||||
" cacop 0xa, %[addr], 12 \n"
|
|
||||||
" cacop 0xa, %[addr], 13 \n"
|
|
||||||
" cacop 0xa, %[addr], 14 \n"
|
|
||||||
" cacop 0xa, %[addr], 15 \n"
|
|
||||||
" addi.w %[vsets], %[vsets], -1 \n"
|
|
||||||
" addi.d %[addr], %[addr], 0x40 \n"
|
|
||||||
" bnez %[vsets], 2b \n"
|
|
||||||
" li.w %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
|
|
||||||
" st.w %[val], %[state_addr], 0 \n"
|
|
||||||
" dbar 0 \n"
|
|
||||||
" cacop 0x11, %[state_addr], 0 \n" /* flush entry of *state_addr */
|
|
||||||
: [addr] "=&r" (addr), [val] "=&r" (val)
|
|
||||||
: [state_addr] "r" (state_addr),
|
|
||||||
[sets] "r" (cpu_data[smp_processor_id()].dcache.sets),
|
|
||||||
[vsets] "r" (cpu_data[smp_processor_id()].vcache.sets));
|
|
||||||
|
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
change_csr_ecfg(ECFG0_IM, ECFGF_IPI);
|
set_csr_ecfg(ECFGF_IPI);
|
||||||
|
__this_cpu_write(cpu_state, CPU_DEAD);
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__smp_mb();
|
||||||
" idle 0 \n"
|
do {
|
||||||
" li.w $t0, 0x1020 \n"
|
__asm__ __volatile__("idle 0\n\t");
|
||||||
" iocsrrd.d %[init_fn], $t0 \n" /* Get init PC */
|
addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
|
||||||
: [init_fn] "=&r" (addr)
|
} while (addr == 0);
|
||||||
: /* No Input */
|
|
||||||
: "a0");
|
init_fn = (void *)TO_CACHE(addr);
|
||||||
init_fn = __va(addr);
|
iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);
|
||||||
|
|
||||||
init_fn();
|
init_fn();
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_dead(void)
|
|
||||||
{
|
|
||||||
int *state_addr;
|
|
||||||
unsigned int cpu = smp_processor_id();
|
|
||||||
void (*play_dead_uncached)(int *s);
|
|
||||||
|
|
||||||
idle_task_exit();
|
|
||||||
play_dead_uncached = (void *)TO_UNCACHE(__pa((unsigned long)loongson3_play_dead));
|
|
||||||
state_addr = &per_cpu(cpu_state, cpu);
|
|
||||||
mb();
|
|
||||||
play_dead_uncached(state_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int loongson3_enable_clock(unsigned int cpu)
|
|
||||||
{
|
|
||||||
uint64_t core_id = cpu_data[cpu].core;
|
|
||||||
uint64_t package_id = cpu_data[cpu].package;
|
|
||||||
|
|
||||||
LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int loongson3_disable_clock(unsigned int cpu)
|
|
||||||
{
|
|
||||||
uint64_t core_id = cpu_data[cpu].core;
|
|
||||||
uint64_t package_id = cpu_data[cpu].package;
|
|
||||||
|
|
||||||
LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int register_loongson3_notifier(void)
|
|
||||||
{
|
|
||||||
return cpuhp_setup_state_nocalls(CPUHP_LOONGARCH_SOC_PREPARE,
|
|
||||||
"loongarch/loongson:prepare",
|
|
||||||
loongson3_enable_clock,
|
|
||||||
loongson3_disable_clock);
|
|
||||||
}
|
|
||||||
early_initcall(register_loongson3_notifier);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ SYM_FUNC_START(__clear_user)
|
||||||
1: st.b zero, a0, 0
|
1: st.b zero, a0, 0
|
||||||
addi.d a0, a0, 1
|
addi.d a0, a0, 1
|
||||||
addi.d a1, a1, -1
|
addi.d a1, a1, -1
|
||||||
bgt a1, zero, 1b
|
bgtz a1, 1b
|
||||||
|
|
||||||
2: move a0, a1
|
2: move a0, a1
|
||||||
jr ra
|
jr ra
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ SYM_FUNC_START(__copy_user)
|
||||||
addi.d a0, a0, 1
|
addi.d a0, a0, 1
|
||||||
addi.d a1, a1, 1
|
addi.d a1, a1, 1
|
||||||
addi.d a2, a2, -1
|
addi.d a2, a2, -1
|
||||||
bgt a2, zero, 1b
|
bgtz a2, 1b
|
||||||
|
|
||||||
3: move a0, a2
|
3: move a0, a2
|
||||||
jr ra
|
jr ra
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/timex.h>
|
#include <linux/timex.h>
|
||||||
|
|
||||||
#include <asm/compiler.h>
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
void __delay(unsigned long cycles)
|
void __delay(unsigned long cycles)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ SYM_FUNC_START(clear_page)
|
||||||
st.d zero, a0, -8
|
st.d zero, a0, -8
|
||||||
bne t0, a0, 1b
|
bne t0, a0, 1b
|
||||||
|
|
||||||
jirl $r0, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(clear_page)
|
SYM_FUNC_END(clear_page)
|
||||||
EXPORT_SYMBOL(clear_page)
|
EXPORT_SYMBOL(clear_page)
|
||||||
|
|
||||||
|
|
@ -79,6 +79,6 @@ SYM_FUNC_START(copy_page)
|
||||||
st.d t7, a0, -8
|
st.d t7, a0, -8
|
||||||
|
|
||||||
bne t8, a0, 1b
|
bne t8, a0, 1b
|
||||||
jirl $r0, ra, 0
|
jr ra
|
||||||
SYM_FUNC_END(copy_page)
|
SYM_FUNC_END(copy_page)
|
||||||
EXPORT_SYMBOL(copy_page)
|
EXPORT_SYMBOL(copy_page)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ SYM_FUNC_START(handle_tlb_load)
|
||||||
* The vmalloc handling is not in the hotpath.
|
* The vmalloc handling is not in the hotpath.
|
||||||
*/
|
*/
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
blt t0, $r0, vmalloc_load
|
bltz t0, vmalloc_load
|
||||||
csrrd t1, LOONGARCH_CSR_PGDL
|
csrrd t1, LOONGARCH_CSR_PGDL
|
||||||
|
|
||||||
vmalloc_done_load:
|
vmalloc_done_load:
|
||||||
|
|
@ -80,7 +80,7 @@ vmalloc_done_load:
|
||||||
* see if we need to jump to huge tlb processing.
|
* see if we need to jump to huge tlb processing.
|
||||||
*/
|
*/
|
||||||
andi t0, ra, _PAGE_HUGE
|
andi t0, ra, _PAGE_HUGE
|
||||||
bne t0, $r0, tlb_huge_update_load
|
bnez t0, tlb_huge_update_load
|
||||||
|
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
||||||
|
|
@ -100,12 +100,12 @@ smp_pgtable_change_load:
|
||||||
|
|
||||||
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
||||||
andi ra, ra, 1
|
andi ra, ra, 1
|
||||||
beq ra, $r0, nopage_tlb_load
|
beqz ra, nopage_tlb_load
|
||||||
|
|
||||||
ori t0, t0, _PAGE_VALID
|
ori t0, t0, _PAGE_VALID
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, smp_pgtable_change_load
|
beqz t0, smp_pgtable_change_load
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -139,23 +139,23 @@ tlb_huge_update_load:
|
||||||
#endif
|
#endif
|
||||||
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
||||||
andi ra, ra, 1
|
andi ra, ra, 1
|
||||||
beq ra, $r0, nopage_tlb_load
|
beqz ra, nopage_tlb_load
|
||||||
tlbsrch
|
tlbsrch
|
||||||
|
|
||||||
ori t0, t0, _PAGE_VALID
|
ori t0, t0, _PAGE_VALID
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, tlb_huge_update_load
|
beqz t0, tlb_huge_update_load
|
||||||
ld.d t0, t1, 0
|
ld.d t0, t1, 0
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
#endif
|
#endif
|
||||||
addu16i.d t1, $r0, -(CSR_TLBIDX_EHINV >> 16)
|
addu16i.d t1, zero, -(CSR_TLBIDX_EHINV >> 16)
|
||||||
addi.d ra, t1, 0
|
addi.d ra, t1, 0
|
||||||
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
|
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
|
||||||
tlbwr
|
tlbwr
|
||||||
|
|
||||||
csrxchg $r0, t1, LOONGARCH_CSR_TLBIDX
|
csrxchg zero, t1, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A huge PTE describes an area the size of the
|
* A huge PTE describes an area the size of the
|
||||||
|
|
@ -178,27 +178,27 @@ tlb_huge_update_load:
|
||||||
addi.d t0, ra, 0
|
addi.d t0, ra, 0
|
||||||
|
|
||||||
/* Convert to entrylo1 */
|
/* Convert to entrylo1 */
|
||||||
addi.d t1, $r0, 1
|
addi.d t1, zero, 1
|
||||||
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
||||||
add.d t0, t0, t1
|
add.d t0, t0, t1
|
||||||
csrwr t0, LOONGARCH_CSR_TLBELO1
|
csrwr t0, LOONGARCH_CSR_TLBELO1
|
||||||
|
|
||||||
/* Set huge page tlb entry size */
|
/* Set huge page tlb entry size */
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
tlbfill
|
tlbfill
|
||||||
|
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
nopage_tlb_load:
|
nopage_tlb_load:
|
||||||
dbar 0
|
dbar 0
|
||||||
csrrd ra, EXCEPTION_KS2
|
csrrd ra, EXCEPTION_KS2
|
||||||
la.abs t0, tlb_do_page_fault_0
|
la.abs t0, tlb_do_page_fault_0
|
||||||
jirl $r0, t0, 0
|
jr t0
|
||||||
SYM_FUNC_END(handle_tlb_load)
|
SYM_FUNC_END(handle_tlb_load)
|
||||||
|
|
||||||
SYM_FUNC_START(handle_tlb_store)
|
SYM_FUNC_START(handle_tlb_store)
|
||||||
|
|
@ -210,7 +210,7 @@ SYM_FUNC_START(handle_tlb_store)
|
||||||
* The vmalloc handling is not in the hotpath.
|
* The vmalloc handling is not in the hotpath.
|
||||||
*/
|
*/
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
blt t0, $r0, vmalloc_store
|
bltz t0, vmalloc_store
|
||||||
csrrd t1, LOONGARCH_CSR_PGDL
|
csrrd t1, LOONGARCH_CSR_PGDL
|
||||||
|
|
||||||
vmalloc_done_store:
|
vmalloc_done_store:
|
||||||
|
|
@ -244,7 +244,7 @@ vmalloc_done_store:
|
||||||
* see if we need to jump to huge tlb processing.
|
* see if we need to jump to huge tlb processing.
|
||||||
*/
|
*/
|
||||||
andi t0, ra, _PAGE_HUGE
|
andi t0, ra, _PAGE_HUGE
|
||||||
bne t0, $r0, tlb_huge_update_store
|
bnez t0, tlb_huge_update_store
|
||||||
|
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
||||||
|
|
@ -265,12 +265,12 @@ smp_pgtable_change_store:
|
||||||
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
||||||
andi ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
andi ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
||||||
xori ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
xori ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
||||||
bne ra, $r0, nopage_tlb_store
|
bnez ra, nopage_tlb_store
|
||||||
|
|
||||||
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, smp_pgtable_change_store
|
beqz t0, smp_pgtable_change_store
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -306,24 +306,24 @@ tlb_huge_update_store:
|
||||||
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
srli.d ra, t0, _PAGE_PRESENT_SHIFT
|
||||||
andi ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
andi ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
||||||
xori ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
xori ra, ra, ((_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT)
|
||||||
bne ra, $r0, nopage_tlb_store
|
bnez ra, nopage_tlb_store
|
||||||
|
|
||||||
tlbsrch
|
tlbsrch
|
||||||
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, tlb_huge_update_store
|
beqz t0, tlb_huge_update_store
|
||||||
ld.d t0, t1, 0
|
ld.d t0, t1, 0
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
#endif
|
#endif
|
||||||
addu16i.d t1, $r0, -(CSR_TLBIDX_EHINV >> 16)
|
addu16i.d t1, zero, -(CSR_TLBIDX_EHINV >> 16)
|
||||||
addi.d ra, t1, 0
|
addi.d ra, t1, 0
|
||||||
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
|
csrxchg ra, t1, LOONGARCH_CSR_TLBIDX
|
||||||
tlbwr
|
tlbwr
|
||||||
|
|
||||||
csrxchg $r0, t1, LOONGARCH_CSR_TLBIDX
|
csrxchg zero, t1, LOONGARCH_CSR_TLBIDX
|
||||||
/*
|
/*
|
||||||
* A huge PTE describes an area the size of the
|
* A huge PTE describes an area the size of the
|
||||||
* configured huge page size. This is twice the
|
* configured huge page size. This is twice the
|
||||||
|
|
@ -345,28 +345,28 @@ tlb_huge_update_store:
|
||||||
addi.d t0, ra, 0
|
addi.d t0, ra, 0
|
||||||
|
|
||||||
/* Convert to entrylo1 */
|
/* Convert to entrylo1 */
|
||||||
addi.d t1, $r0, 1
|
addi.d t1, zero, 1
|
||||||
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
||||||
add.d t0, t0, t1
|
add.d t0, t0, t1
|
||||||
csrwr t0, LOONGARCH_CSR_TLBELO1
|
csrwr t0, LOONGARCH_CSR_TLBELO1
|
||||||
|
|
||||||
/* Set huge page tlb entry size */
|
/* Set huge page tlb entry size */
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
tlbfill
|
tlbfill
|
||||||
|
|
||||||
/* Reset default page size */
|
/* Reset default page size */
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
nopage_tlb_store:
|
nopage_tlb_store:
|
||||||
dbar 0
|
dbar 0
|
||||||
csrrd ra, EXCEPTION_KS2
|
csrrd ra, EXCEPTION_KS2
|
||||||
la.abs t0, tlb_do_page_fault_1
|
la.abs t0, tlb_do_page_fault_1
|
||||||
jirl $r0, t0, 0
|
jr t0
|
||||||
SYM_FUNC_END(handle_tlb_store)
|
SYM_FUNC_END(handle_tlb_store)
|
||||||
|
|
||||||
SYM_FUNC_START(handle_tlb_modify)
|
SYM_FUNC_START(handle_tlb_modify)
|
||||||
|
|
@ -378,7 +378,7 @@ SYM_FUNC_START(handle_tlb_modify)
|
||||||
* The vmalloc handling is not in the hotpath.
|
* The vmalloc handling is not in the hotpath.
|
||||||
*/
|
*/
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
blt t0, $r0, vmalloc_modify
|
bltz t0, vmalloc_modify
|
||||||
csrrd t1, LOONGARCH_CSR_PGDL
|
csrrd t1, LOONGARCH_CSR_PGDL
|
||||||
|
|
||||||
vmalloc_done_modify:
|
vmalloc_done_modify:
|
||||||
|
|
@ -411,7 +411,7 @@ vmalloc_done_modify:
|
||||||
* see if we need to jump to huge tlb processing.
|
* see if we need to jump to huge tlb processing.
|
||||||
*/
|
*/
|
||||||
andi t0, ra, _PAGE_HUGE
|
andi t0, ra, _PAGE_HUGE
|
||||||
bne t0, $r0, tlb_huge_update_modify
|
bnez t0, tlb_huge_update_modify
|
||||||
|
|
||||||
csrrd t0, LOONGARCH_CSR_BADV
|
csrrd t0, LOONGARCH_CSR_BADV
|
||||||
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
srli.d t0, t0, (PAGE_SHIFT + PTE_ORDER)
|
||||||
|
|
@ -431,12 +431,12 @@ smp_pgtable_change_modify:
|
||||||
|
|
||||||
srli.d ra, t0, _PAGE_WRITE_SHIFT
|
srli.d ra, t0, _PAGE_WRITE_SHIFT
|
||||||
andi ra, ra, 1
|
andi ra, ra, 1
|
||||||
beq ra, $r0, nopage_tlb_modify
|
beqz ra, nopage_tlb_modify
|
||||||
|
|
||||||
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, smp_pgtable_change_modify
|
beqz t0, smp_pgtable_change_modify
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -471,14 +471,14 @@ tlb_huge_update_modify:
|
||||||
|
|
||||||
srli.d ra, t0, _PAGE_WRITE_SHIFT
|
srli.d ra, t0, _PAGE_WRITE_SHIFT
|
||||||
andi ra, ra, 1
|
andi ra, ra, 1
|
||||||
beq ra, $r0, nopage_tlb_modify
|
beqz ra, nopage_tlb_modify
|
||||||
|
|
||||||
tlbsrch
|
tlbsrch
|
||||||
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
ori t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
sc.d t0, t1, 0
|
sc.d t0, t1, 0
|
||||||
beq t0, $r0, tlb_huge_update_modify
|
beqz t0, tlb_huge_update_modify
|
||||||
ld.d t0, t1, 0
|
ld.d t0, t1, 0
|
||||||
#else
|
#else
|
||||||
st.d t0, t1, 0
|
st.d t0, t1, 0
|
||||||
|
|
@ -504,28 +504,28 @@ tlb_huge_update_modify:
|
||||||
addi.d t0, ra, 0
|
addi.d t0, ra, 0
|
||||||
|
|
||||||
/* Convert to entrylo1 */
|
/* Convert to entrylo1 */
|
||||||
addi.d t1, $r0, 1
|
addi.d t1, zero, 1
|
||||||
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
slli.d t1, t1, (HPAGE_SHIFT - 1)
|
||||||
add.d t0, t0, t1
|
add.d t0, t0, t1
|
||||||
csrwr t0, LOONGARCH_CSR_TLBELO1
|
csrwr t0, LOONGARCH_CSR_TLBELO1
|
||||||
|
|
||||||
/* Set huge page tlb entry size */
|
/* Set huge page tlb entry size */
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
tlbwr
|
tlbwr
|
||||||
|
|
||||||
/* Reset default page size */
|
/* Reset default page size */
|
||||||
addu16i.d t0, $r0, (CSR_TLBIDX_PS >> 16)
|
addu16i.d t0, zero, (CSR_TLBIDX_PS >> 16)
|
||||||
addu16i.d t1, $r0, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
addu16i.d t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
|
||||||
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
csrxchg t1, t0, LOONGARCH_CSR_TLBIDX
|
||||||
|
|
||||||
nopage_tlb_modify:
|
nopage_tlb_modify:
|
||||||
dbar 0
|
dbar 0
|
||||||
csrrd ra, EXCEPTION_KS2
|
csrrd ra, EXCEPTION_KS2
|
||||||
la.abs t0, tlb_do_page_fault_1
|
la.abs t0, tlb_do_page_fault_1
|
||||||
jirl $r0, t0, 0
|
jr t0
|
||||||
SYM_FUNC_END(handle_tlb_modify)
|
SYM_FUNC_END(handle_tlb_modify)
|
||||||
|
|
||||||
SYM_FUNC_START(handle_tlb_refill)
|
SYM_FUNC_START(handle_tlb_refill)
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,7 @@ config PPC
|
||||||
select IRQ_FORCED_THREADING
|
select IRQ_FORCED_THREADING
|
||||||
select MMU_GATHER_PAGE_SIZE
|
select MMU_GATHER_PAGE_SIZE
|
||||||
select MMU_GATHER_RCU_TABLE_FREE
|
select MMU_GATHER_RCU_TABLE_FREE
|
||||||
|
select MMU_GATHER_MERGE_VMAS
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
select NEED_DMA_MAP_STATE if PPC64 || NOT_COHERENT_CACHE
|
select NEED_DMA_MAP_STATE if PPC64 || NOT_COHERENT_CACHE
|
||||||
select NEED_PER_CPU_EMBED_FIRST_CHUNK if PPC64
|
select NEED_PER_CPU_EMBED_FIRST_CHUNK if PPC64
|
||||||
|
|
@ -281,6 +282,10 @@ config PPC
|
||||||
# Please keep this list sorted alphabetically.
|
# Please keep this list sorted alphabetically.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
config PPC_LONG_DOUBLE_128
|
||||||
|
depends on PPC64
|
||||||
|
def_bool $(success,test "$(shell,echo __LONG_DOUBLE_128__ | $(CC) -E -P -)" = 1)
|
||||||
|
|
||||||
config PPC_BARRIER_NOSPEC
|
config PPC_BARRIER_NOSPEC
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
|
|
||||||
#define tlb_start_vma(tlb, vma) do { } while (0)
|
|
||||||
#define tlb_end_vma(tlb, vma) do { } while (0)
|
|
||||||
#define __tlb_remove_tlb_entry __tlb_remove_tlb_entry
|
#define __tlb_remove_tlb_entry __tlb_remove_tlb_entry
|
||||||
|
|
||||||
#define tlb_flush tlb_flush
|
#define tlb_flush tlb_flush
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
|
||||||
CFLAGS_prom_init.o += -fno-stack-protector
|
CFLAGS_prom_init.o += -fno-stack-protector
|
||||||
CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING
|
CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING
|
||||||
CFLAGS_prom_init.o += -ffreestanding
|
CFLAGS_prom_init.o += -ffreestanding
|
||||||
|
CFLAGS_prom_init.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized)
|
||||||
|
|
||||||
ifdef CONFIG_FUNCTION_TRACER
|
ifdef CONFIG_FUNCTION_TRACER
|
||||||
# Do not trace early boot code
|
# Do not trace early boot code
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ ifeq ($(CONFIG_PERF_EVENTS),y)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
|
KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
|
||||||
|
KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
|
||||||
|
|
||||||
# GCC versions that support the "-mstrict-align" option default to allowing
|
# GCC versions that support the "-mstrict-align" option default to allowing
|
||||||
# unaligned accesses. While unaligned accesses are explicitly allowed in the
|
# unaligned accesses. While unaligned accesses are explicitly allowed in the
|
||||||
|
|
@ -110,7 +111,7 @@ PHONY += vdso_install
|
||||||
vdso_install:
|
vdso_install:
|
||||||
$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
|
$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
|
||||||
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||||
$(build)=arch/riscv/kernel/compat_vdso $@)
|
$(build)=arch/riscv/kernel/compat_vdso compat_$@)
|
||||||
|
|
||||||
ifeq ($(KBUILD_EXTMOD),)
|
ifeq ($(KBUILD_EXTMOD),)
|
||||||
ifeq ($(CONFIG_MMU),y)
|
ifeq ($(CONFIG_MMU),y)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ led1 {
|
||||||
gpio-keys {
|
gpio-keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
key0 {
|
key {
|
||||||
label = "KEY0";
|
label = "KEY0";
|
||||||
linux,code = <BTN_0>;
|
linux,code = <BTN_0>;
|
||||||
gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ led2 {
|
||||||
gpio-keys {
|
gpio-keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
boot {
|
key-boot {
|
||||||
label = "BOOT";
|
label = "BOOT";
|
||||||
linux,code = <BTN_0>;
|
linux,code = <BTN_0>;
|
||||||
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ led2 {
|
||||||
gpio-keys {
|
gpio-keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
boot {
|
key-boot {
|
||||||
label = "BOOT";
|
label = "BOOT";
|
||||||
linux,code = <BTN_0>;
|
linux,code = <BTN_0>;
|
||||||
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||||
|
|
|
||||||
|
|
@ -46,19 +46,19 @@ led2 {
|
||||||
gpio-keys {
|
gpio-keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
up {
|
key-up {
|
||||||
label = "UP";
|
label = "UP";
|
||||||
linux,code = <BTN_1>;
|
linux,code = <BTN_1>;
|
||||||
gpios = <&gpio1_0 7 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio1_0 7 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
|
|
||||||
press {
|
key-press {
|
||||||
label = "PRESS";
|
label = "PRESS";
|
||||||
linux,code = <BTN_0>;
|
linux,code = <BTN_0>;
|
||||||
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
|
|
||||||
down {
|
key-down {
|
||||||
label = "DOWN";
|
label = "DOWN";
|
||||||
linux,code = <BTN_2>;
|
linux,code = <BTN_2>;
|
||||||
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ chosen {
|
||||||
gpio-keys {
|
gpio-keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
boot {
|
key-boot {
|
||||||
label = "BOOT";
|
label = "BOOT";
|
||||||
linux,code = <BTN_0>;
|
linux,code = <BTN_0>;
|
||||||
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ cpu1: cpu@1 {
|
||||||
riscv,isa = "rv64imafdc";
|
riscv,isa = "rv64imafdc";
|
||||||
clocks = <&clkcfg CLK_CPU>;
|
clocks = <&clkcfg CLK_CPU>;
|
||||||
tlb-split;
|
tlb-split;
|
||||||
|
next-level-cache = <&cctrllr>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
cpu1_intc: interrupt-controller {
|
cpu1_intc: interrupt-controller {
|
||||||
|
|
@ -77,6 +78,7 @@ cpu2: cpu@2 {
|
||||||
riscv,isa = "rv64imafdc";
|
riscv,isa = "rv64imafdc";
|
||||||
clocks = <&clkcfg CLK_CPU>;
|
clocks = <&clkcfg CLK_CPU>;
|
||||||
tlb-split;
|
tlb-split;
|
||||||
|
next-level-cache = <&cctrllr>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
cpu2_intc: interrupt-controller {
|
cpu2_intc: interrupt-controller {
|
||||||
|
|
@ -104,6 +106,7 @@ cpu3: cpu@3 {
|
||||||
riscv,isa = "rv64imafdc";
|
riscv,isa = "rv64imafdc";
|
||||||
clocks = <&clkcfg CLK_CPU>;
|
clocks = <&clkcfg CLK_CPU>;
|
||||||
tlb-split;
|
tlb-split;
|
||||||
|
next-level-cache = <&cctrllr>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
cpu3_intc: interrupt-controller {
|
cpu3_intc: interrupt-controller {
|
||||||
|
|
@ -131,6 +134,7 @@ cpu4: cpu@4 {
|
||||||
riscv,isa = "rv64imafdc";
|
riscv,isa = "rv64imafdc";
|
||||||
clocks = <&clkcfg CLK_CPU>;
|
clocks = <&clkcfg CLK_CPU>;
|
||||||
tlb-split;
|
tlb-split;
|
||||||
|
next-level-cache = <&cctrllr>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
cpu4_intc: interrupt-controller {
|
cpu4_intc: interrupt-controller {
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ void __init_or_module sifive_errata_patch_func(struct alt_entry *begin,
|
||||||
cpu_apply_errata |= tmp;
|
cpu_apply_errata |= tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cpu_apply_errata != cpu_req_errata)
|
if (stage != RISCV_ALTERNATIVES_MODULE &&
|
||||||
|
cpu_apply_errata != cpu_req_errata)
|
||||||
warn_miss_errata(cpu_req_errata - cpu_apply_errata);
|
warn_miss_errata(cpu_req_errata - cpu_apply_errata);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
|
||||||
|
|
||||||
static inline unsigned long _pud_pfn(pud_t pud)
|
static inline unsigned long _pud_pfn(pud_t pud)
|
||||||
{
|
{
|
||||||
return pud_val(pud) >> _PAGE_PFN_SHIFT;
|
return __page_val_to_pfn(pud_val(pud));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pmd_t *pud_pgtable(pud_t pud)
|
static inline pmd_t *pud_pgtable(pud_t pud)
|
||||||
|
|
@ -278,13 +278,13 @@ static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
|
||||||
|
|
||||||
static inline unsigned long _p4d_pfn(p4d_t p4d)
|
static inline unsigned long _p4d_pfn(p4d_t p4d)
|
||||||
{
|
{
|
||||||
return p4d_val(p4d) >> _PAGE_PFN_SHIFT;
|
return __page_val_to_pfn(p4d_val(p4d));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pud_t *p4d_pgtable(p4d_t p4d)
|
static inline pud_t *p4d_pgtable(p4d_t p4d)
|
||||||
{
|
{
|
||||||
if (pgtable_l4_enabled)
|
if (pgtable_l4_enabled)
|
||||||
return (pud_t *)pfn_to_virt(p4d_val(p4d) >> _PAGE_PFN_SHIFT);
|
return (pud_t *)pfn_to_virt(__page_val_to_pfn(p4d_val(p4d)));
|
||||||
|
|
||||||
return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) });
|
return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) });
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +292,7 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
|
||||||
|
|
||||||
static inline struct page *p4d_page(p4d_t p4d)
|
static inline struct page *p4d_page(p4d_t p4d)
|
||||||
{
|
{
|
||||||
return pfn_to_page(p4d_val(p4d) >> _PAGE_PFN_SHIFT);
|
return pfn_to_page(__page_val_to_pfn(p4d_val(p4d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
|
#define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
|
||||||
|
|
@ -347,7 +347,7 @@ static inline void pgd_clear(pgd_t *pgd)
|
||||||
static inline p4d_t *pgd_pgtable(pgd_t pgd)
|
static inline p4d_t *pgd_pgtable(pgd_t pgd)
|
||||||
{
|
{
|
||||||
if (pgtable_l5_enabled)
|
if (pgtable_l5_enabled)
|
||||||
return (p4d_t *)pfn_to_virt(pgd_val(pgd) >> _PAGE_PFN_SHIFT);
|
return (p4d_t *)pfn_to_virt(__page_val_to_pfn(pgd_val(pgd)));
|
||||||
|
|
||||||
return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) });
|
return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) });
|
||||||
}
|
}
|
||||||
|
|
@ -355,7 +355,7 @@ static inline p4d_t *pgd_pgtable(pgd_t pgd)
|
||||||
|
|
||||||
static inline struct page *pgd_page(pgd_t pgd)
|
static inline struct page *pgd_page(pgd_t pgd)
|
||||||
{
|
{
|
||||||
return pfn_to_page(pgd_val(pgd) >> _PAGE_PFN_SHIFT);
|
return pfn_to_page(__page_val_to_pfn(pgd_val(pgd)));
|
||||||
}
|
}
|
||||||
#define pgd_page(pgd) pgd_page(pgd)
|
#define pgd_page(pgd) pgd_page(pgd)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,7 @@ static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
|
||||||
|
|
||||||
static inline unsigned long _pgd_pfn(pgd_t pgd)
|
static inline unsigned long _pgd_pfn(pgd_t pgd)
|
||||||
{
|
{
|
||||||
return pgd_val(pgd) >> _PAGE_PFN_SHIFT;
|
return __page_val_to_pfn(pgd_val(pgd));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct page *pmd_page(pmd_t pmd)
|
static inline struct page *pmd_page(pmd_t pmd)
|
||||||
|
|
@ -590,14 +590,14 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd)
|
||||||
return __pmd(pmd_val(pmd) & ~(_PAGE_PRESENT|_PAGE_PROT_NONE));
|
return __pmd(pmd_val(pmd) & ~(_PAGE_PRESENT|_PAGE_PROT_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __pmd_to_phys(pmd) (pmd_val(pmd) >> _PAGE_PFN_SHIFT << PAGE_SHIFT)
|
#define __pmd_to_phys(pmd) (__page_val_to_pfn(pmd_val(pmd)) << PAGE_SHIFT)
|
||||||
|
|
||||||
static inline unsigned long pmd_pfn(pmd_t pmd)
|
static inline unsigned long pmd_pfn(pmd_t pmd)
|
||||||
{
|
{
|
||||||
return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT);
|
return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __pud_to_phys(pud) (pud_val(pud) >> _PAGE_PFN_SHIFT << PAGE_SHIFT)
|
#define __pud_to_phys(pud) (__page_val_to_pfn(pud_val(pud)) << PAGE_SHIFT)
|
||||||
|
|
||||||
static inline unsigned long pud_pfn(pud_t pud)
|
static inline unsigned long pud_pfn(pud_t pud)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ obj-$(CONFIG_SMP) += cpu_ops_sbi.o
|
||||||
endif
|
endif
|
||||||
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
|
obj-$(CONFIG_HOTPLUG_CPU) += cpu-hotplug.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb.o
|
obj-$(CONFIG_KGDB) += kgdb.o
|
||||||
obj-$(CONFIG_KEXEC) += kexec_relocate.o crash_save_regs.o machine_kexec.o
|
obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
|
||||||
obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
|
obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
|
||||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
|
||||||
{
|
{
|
||||||
const char *strtab, *name, *shstrtab;
|
const char *strtab, *name, *shstrtab;
|
||||||
const Elf_Shdr *sechdrs;
|
const Elf_Shdr *sechdrs;
|
||||||
Elf_Rela *relas;
|
Elf64_Rela *relas;
|
||||||
int i, r_type;
|
int i, r_type;
|
||||||
|
|
||||||
/* String & section header string table */
|
/* String & section header string table */
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ static inline unsigned long gstage_pte_index(gpa_t addr, u32 level)
|
||||||
|
|
||||||
static inline unsigned long gstage_pte_page_vaddr(pte_t pte)
|
static inline unsigned long gstage_pte_page_vaddr(pte_t pte)
|
||||||
{
|
{
|
||||||
return (unsigned long)pfn_to_virt(pte_val(pte) >> _PAGE_PFN_SHIFT);
|
return (unsigned long)pfn_to_virt(__page_val_to_pfn(pte_val(pte)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gstage_page_size_to_level(unsigned long page_size, u32 *out_level)
|
static int gstage_page_size_to_level(unsigned long page_size, u32 *out_level)
|
||||||
|
|
|
||||||
|
|
@ -781,9 +781,11 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
if (kvm_request_pending(vcpu)) {
|
if (kvm_request_pending(vcpu)) {
|
||||||
if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) {
|
if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) {
|
||||||
|
kvm_vcpu_srcu_read_unlock(vcpu);
|
||||||
rcuwait_wait_event(wait,
|
rcuwait_wait_event(wait,
|
||||||
(!vcpu->arch.power_off) && (!vcpu->arch.pause),
|
(!vcpu->arch.power_off) && (!vcpu->arch.pause),
|
||||||
TASK_INTERRUPTIBLE);
|
TASK_INTERRUPTIBLE);
|
||||||
|
kvm_vcpu_srcu_read_lock(vcpu);
|
||||||
|
|
||||||
if (vcpu->arch.power_off || vcpu->arch.pause) {
|
if (vcpu->arch.power_off || vcpu->arch.pause) {
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ config S390
|
||||||
select IOMMU_SUPPORT if PCI
|
select IOMMU_SUPPORT if PCI
|
||||||
select MMU_GATHER_NO_GATHER
|
select MMU_GATHER_NO_GATHER
|
||||||
select MMU_GATHER_RCU_TABLE_FREE
|
select MMU_GATHER_RCU_TABLE_FREE
|
||||||
|
select MMU_GATHER_MERGE_VMAS
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
select NEED_DMA_MAP_STATE if PCI
|
select NEED_DMA_MAP_STATE if PCI
|
||||||
select NEED_SG_DMA_LENGTH if PCI
|
select NEED_SG_DMA_LENGTH if PCI
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ endif
|
||||||
|
|
||||||
ifdef CONFIG_EXPOLINE
|
ifdef CONFIG_EXPOLINE
|
||||||
ifdef CONFIG_EXPOLINE_EXTERN
|
ifdef CONFIG_EXPOLINE_EXTERN
|
||||||
KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline.o
|
KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline/expoline.o
|
||||||
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
|
CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
|
||||||
CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern
|
CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern
|
||||||
else
|
else
|
||||||
|
|
@ -163,6 +163,12 @@ vdso_prepare: prepare0
|
||||||
$(Q)$(MAKE) $(build)=arch/s390/kernel/vdso64 include/generated/vdso64-offsets.h
|
$(Q)$(MAKE) $(build)=arch/s390/kernel/vdso64 include/generated/vdso64-offsets.h
|
||||||
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
|
||||||
$(build)=arch/s390/kernel/vdso32 include/generated/vdso32-offsets.h)
|
$(build)=arch/s390/kernel/vdso32 include/generated/vdso32-offsets.h)
|
||||||
|
|
||||||
|
ifdef CONFIG_EXPOLINE_EXTERN
|
||||||
|
modules_prepare: expoline_prepare
|
||||||
|
expoline_prepare:
|
||||||
|
$(Q)$(MAKE) $(build)=arch/s390/lib/expoline arch/s390/lib/expoline/expoline.o
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Don't use tabs in echo arguments
|
# Don't use tabs in echo arguments
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user