Commit 45763bf4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver updates from Greg KH:
 "Here is the big char/misc driver patch pull request for 5.1-rc1.

  The largest thing by far is the new habanalabs driver for their AI
  accelerator chip. For now it is in the drivers/misc directory but will
  probably move to a new directory soon along with other drivers of this
  type.

  Other than that, just the usual set of individual driver updates and
  fixes. There's an "odd" merge in here from the DRM tree that they
  asked me to do as the MEI driver is starting to interact with the i915
  driver, and it needed some coordination. All of those patches have
  been properly acked by the relevant subsystem maintainers.

  All of these have been in linux-next with no reported issues, most for
  quite some time"

* tag 'char-misc-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (219 commits)
  habanalabs: adjust Kconfig to fix build errors
  habanalabs: use %px instead of %p in error print
  habanalabs: use do_div for 64-bit divisions
  intel_th: gth: Fix an off-by-one in output unassigning
  habanalabs: fix little-endian<->cpu conversion warnings
  habanalabs: use NULL to initialize array of pointers
  habanalabs: fix little-endian<->cpu conversion warnings
  habanalabs: soft-reset device if context-switch fails
  habanalabs: print pointer using %p
  habanalabs: fix memory leak with CBs with unaligned size
  habanalabs: return correct error code on MMU mapping failure
  habanalabs: add comments in uapi/misc/habanalabs.h
  habanalabs: extend QMAN0 job timeout
  habanalabs: set DMA0 completion to SOB 1007
  habanalabs: fix validation of WREG32 to DMA completion
  habanalabs: fix mmu cache registers init
  habanalabs: disable CPU access on timeouts
  habanalabs: add MMU DRAM default page mapping
  habanalabs: Dissociate RAZWI info from event types
  misc/habanalabs: adjust Kconfig to fix build errors
  ...
parents da2577fe 142a0f83
......@@ -1221,7 +1221,7 @@ S: Brazil
N: Oded Gabbay
E: oded.gabbay@gmail.com
D: AMD KFD maintainer
D: HabanaLabs and AMD KFD maintainer
S: 12 Shraga Raphaeli
S: Petah-Tikva, 4906418
S: Israel
......
......@@ -146,3 +146,36 @@ KernelVersion: 4.16
Contact: Stephen Hemminger <sthemmin@microsoft.com>
Description: Binary file created by uio_hv_generic for ring buffer
Users: Userspace drivers
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/intr_in_full
Date: February 2019
KernelVersion: 5.0
Contact: Michael Kelley <mikelley@microsoft.com>
Description: Number of guest to host interrupts caused by the inbound ring
buffer transitioning from full to not full while a packet is
waiting for buffer space to become available
Users: Debugging tools
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/intr_out_empty
Date: February 2019
KernelVersion: 5.0
Contact: Michael Kelley <mikelley@microsoft.com>
Description: Number of guest to host interrupts caused by the outbound ring
buffer transitioning from empty to not empty
Users: Debugging tools
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_full_first
Date: February 2019
KernelVersion: 5.0
Contact: Michael Kelley <mikelley@microsoft.com>
Description: Number of write operations that were the first to encounter an
outbound ring buffer full condition
Users: Debugging tools
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_full_total
Date: February 2019
KernelVersion: 5.0
Contact: Michael Kelley <mikelley@microsoft.com>
Description: Total number of write operations that encountered an outbound
ring buffer full condition
Users: Debugging tools
What: /sys/kernel/debug/habanalabs/hl<n>/addr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets the device address to be used for read or write through
PCI bar. The acceptable value is a string that starts with "0x"
What: /sys/kernel/debug/habanalabs/hl<n>/command_buffers
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays a list with information about the currently allocated
command buffers
What: /sys/kernel/debug/habanalabs/hl<n>/command_submission
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays a list with information about the currently active
command submissions
What: /sys/kernel/debug/habanalabs/hl<n>/command_submission_jobs
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays a list with detailed information about each JOB (CB) of
each active command submission
What: /sys/kernel/debug/habanalabs/hl<n>/data32
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the root user to read or write directly through the
device's PCI bar. Writing to this file generates a write
transaction while reading from the file generates a read
transcation. This custom interface is needed (instead of using
the generic Linux user-space PCI mapping) because the DDR bar
is very small compared to the DDR memory and only the driver can
move the bar before and after the transaction
What: /sys/kernel/debug/habanalabs/hl<n>/device
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Enables the root user to set the device to specific state.
Valid values are "disable", "enable", "suspend", "resume".
User can read this property to see the valid values
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_addr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets I2C device address for I2C transaction that is generated
by the device's CPU
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_bus
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets I2C bus address for I2C transaction that is generated by
the device's CPU
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_data
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Triggers an I2C transaction that is generated by the device's
CPU. Writing to this file generates a write transaction while
reading from the file generates a read transcation
What: /sys/kernel/debug/habanalabs/hl<n>/i2c_reg
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets I2C register id for I2C transaction that is generated by
the device's CPU
What: /sys/kernel/debug/habanalabs/hl<n>/led0
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets the state of the first S/W led on the device
What: /sys/kernel/debug/habanalabs/hl<n>/led1
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets the state of the second S/W led on the device
What: /sys/kernel/debug/habanalabs/hl<n>/led2
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets the state of the third S/W led on the device
What: /sys/kernel/debug/habanalabs/hl<n>/mmu
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the hop values and physical address for a given ASID
and virtual address. The user should write the ASID and VA into
the file and then read the file to get the result.
e.g. to display info about VA 0x1000 for ASID 1 you need to do:
echo "1 0x1000" > /sys/kernel/debug/habanalabs/hl0/mmu
What: /sys/kernel/debug/habanalabs/hl<n>/set_power_state
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Sets the PCI power state. Valid values are "1" for D0 and "2"
for D3Hot
What: /sys/kernel/debug/habanalabs/hl<n>/userptr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays a list with information about the currently user
pointers (user virtual addresses) that are pinned and mapped
to DMA addresses
What: /sys/kernel/debug/habanalabs/hl<n>/vm
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays a list with information about all the active virtual
address mappings per ASID
......@@ -3,11 +3,13 @@ Date: June 2015
KernelVersion: 4.3
Contact: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Description: (RW) Writes of 1 or 0 enable or disable trace output to this
output device. Reads return current status.
output device. Reads return current status. Requires that the
correstponding output port driver be loaded.
What: /sys/bus/intel_th/devices/<intel_th_id>-msc<msc-id>/port
Date: June 2015
KernelVersion: 4.3
Contact: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Description: (RO) Port number, corresponding to this output device on the
switch (GTH).
switch (GTH) or "unassigned" if the corresponding output
port driver is not loaded.
What: /sys/class/habanalabs/hl<n>/armcp_kernel_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the Linux kernel running on the device's CPU
What: /sys/class/habanalabs/hl<n>/armcp_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the application running on the device's CPU
What: /sys/class/habanalabs/hl<n>/cpld_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the Device's CPLD F/W
What: /sys/class/habanalabs/hl<n>/device_type
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the code name of the device according to its type.
The supported values are: "GOYA"
What: /sys/class/habanalabs/hl<n>/eeprom
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: A binary file attribute that contains the contents of the
on-board EEPROM
What: /sys/class/habanalabs/hl<n>/fuse_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the device's version from the eFuse
What: /sys/class/habanalabs/hl<n>/hard_reset
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Interface to trigger a hard-reset operation for the device.
Hard-reset will reset ALL internal components of the device
except for the PCI interface and the internal PLLs
What: /sys/class/habanalabs/hl<n>/hard_reset_cnt
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays how many times the device have undergone a hard-reset
operation since the driver was loaded
What: /sys/class/habanalabs/hl<n>/high_pll
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the user to set the maximum clock frequency for MME, TPC
and IC when the power management profile is set to "automatic".
What: /sys/class/habanalabs/hl<n>/ic_clk
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the user to set the maximum clock frequency of the
Interconnect fabric. Writes to this parameter affect the device
only when the power management profile is set to "manual" mode.
The device IC clock might be set to lower value then the
maximum. The user should read the ic_clk_curr to see the actual
frequency value of the IC
What: /sys/class/habanalabs/hl<n>/ic_clk_curr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the current clock frequency of the Interconnect fabric
What: /sys/class/habanalabs/hl<n>/infineon_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the Device's power supply F/W code
What: /sys/class/habanalabs/hl<n>/max_power
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the user to set the maximum power consumption of the
device in milliwatts.
What: /sys/class/habanalabs/hl<n>/mme_clk
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the user to set the maximum clock frequency of the
MME compute engine. Writes to this parameter affect the device
only when the power management profile is set to "manual" mode.
The device MME clock might be set to lower value then the
maximum. The user should read the mme_clk_curr to see the actual
frequency value of the MME
What: /sys/class/habanalabs/hl<n>/mme_clk_curr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the current clock frequency of the MME compute engine
What: /sys/class/habanalabs/hl<n>/pci_addr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the PCI address of the device. This is needed so the
user would be able to open a device based on its PCI address
What: /sys/class/habanalabs/hl<n>/pm_mng_profile
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Power management profile. Values are "auto", "manual". In "auto"
mode, the driver will set the maximum clock frequency to a high
value when a user-space process opens the device's file (unless
it was already opened by another process). The driver will set
the max clock frequency to a low value when there are no user
processes that are opened on the device's file. In "manual"
mode, the user sets the maximum clock frequency by writing to
ic_clk, mme_clk and tpc_clk
What: /sys/class/habanalabs/hl<n>/preboot_btl_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the device's preboot F/W code
What: /sys/class/habanalabs/hl<n>/soft_reset
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Interface to trigger a soft-reset operation for the device.
Soft-reset will reset only the compute and DMA engines of the
device
What: /sys/class/habanalabs/hl<n>/soft_reset_cnt
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays how many times the device have undergone a soft-reset
operation since the driver was loaded
What: /sys/class/habanalabs/hl<n>/status
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Status of the card: "Operational", "Malfunction", "In reset".
What: /sys/class/habanalabs/hl<n>/thermal_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the Device's thermal daemon
What: /sys/class/habanalabs/hl<n>/tpc_clk
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Allows the user to set the maximum clock frequency of the
TPC compute engines. Writes to this parameter affect the device
only when the power management profile is set to "manual" mode.
The device TPC clock might be set to lower value then the
maximum. The user should read the tpc_clk_curr to see the actual
frequency value of the TPC
What: /sys/class/habanalabs/hl<n>/tpc_clk_curr
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the current clock frequency of the TPC compute engines
What: /sys/class/habanalabs/hl<n>/uboot_ver
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Version of the u-boot running on the device's CPU
What: /sys/class/habanalabs/hl<n>/write_open_cnt
Date: Jan 2019
KernelVersion: 5.1
Contact: oded.gabbay@gmail.com
Description: Displays the total number of user processes that are currently
opened on the device's file
* PTN5150 CC (Configuration Channel) Logic device
PTN5150 is a small thin low power CC logic chip supporting the USB Type-C
connector application with CC control logic detection and indication functions.
It is interfaced to the host controller using an I2C interface.
Required properties:
- compatible: should be "nxp,ptn5150"
- reg: specifies the I2C slave address of the device
- int-gpio: should contain a phandle and GPIO specifier for the GPIO pin
connected to the PTN5150's INTB pin.
- vbus-gpio: should contain a phandle and GPIO specifier for the GPIO pin which
is used to control VBUS.
- pinctrl-names : a pinctrl state named "default" must be defined.
- pinctrl-0 : phandle referencing pin configuration of interrupt and vbus
control.
Example:
ptn5150@1d {
compatible = "nxp,ptn5150";
reg = <0x1d>;
int-gpio = <&msmgpio 78 GPIO_ACTIVE_HIGH>;
vbus-gpio = <&msmgpio 148 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&ptn5150_default>;
status = "okay";
};
......@@ -17,6 +17,7 @@ Required properties:
represents
Optional properties:
- lna-supply : Separate supply for an LNA
- enable-gpios : GPIO used to enable the device
- timepulse-gpios : Time pulse GPIO
......
Mediatek-based GNSS Receiver DT binding
Mediatek chipsets are used in GNSS-receiver modules produced by several
vendors and can use a UART interface.
Please see Documentation/devicetree/bindings/gnss/gnss.txt for generic
properties.
Required properties:
- compatible : Must be
"globaltop,pa6h"
- vcc-supply : Main voltage regulator (pin name: VCC)
Optional properties:
- current-speed : Default UART baud rate
- gnss-fix-gpios : GPIO used to determine device position fix state
(pin name: FIX, 3D_FIX)
- reset-gpios : GPIO used to reset the device (pin name: RESET, NRESET)
- timepulse-gpios : Time pulse GPIO (pin name: PPS1, 1PPS)
- vbackup-supply : Backup voltage regulator (pin name: VBAT, VBACKUP)
Example:
serial@1234 {
compatible = "ns16550a";
gnss {
compatible = "globaltop,pa6h";
vcc-supply = <&vcc_3v3>;
};
};
......@@ -12,6 +12,7 @@ Required properties:
"fastrax,uc430"
"linx,r4"
"wi2wi,w2sg0004"
"wi2wi,w2sg0008i"
"wi2wi,w2sg0084i"
......
Interconnect Provider Device Tree Bindings
=========================================
The purpose of this document is to define a common set of generic interconnect
providers/consumers properties.
= interconnect providers =
The interconnect provider binding is intended to represent the interconnect
controllers in the system. Each provider registers a set of interconnect
nodes, which expose the interconnect related capabilities of the interconnect
to consumer drivers. These capabilities can be throughput, latency, priority
etc. The consumer drivers set constraints on interconnect path (or endpoints)
depending on the use case. Interconnect providers can also be interconnect
consumers, such as in the case where two network-on-chip fabrics interface
directly.
Required properties:
- compatible : contains the interconnect provider compatible string
- #interconnect-cells : number of cells in a interconnect specifier needed to
encode the interconnect node id
Example:
snoc: interconnect@580000 {
compatible = "qcom,msm8916-snoc";
#interconnect-cells = <1>;
reg = <0x580000 0x14000>;
clock-names = "bus_clk", "bus_a_clk";
clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
<&rpmcc RPM_SMD_SNOC_A_CLK>;
};
= interconnect consumers =
The interconnect consumers are device nodes which dynamically express their
bandwidth requirements along interconnect paths they are connected to. There
can be multiple interconnect providers on a SoC and the consumer may consume
multiple paths from different providers depending on use case and the
components it has to interact with.
Required properties:
interconnects : Pairs of phandles and interconnect provider specifier to denote
the edge source and destination ports of the interconnect path.
Optional properties:
interconnect-names : List of interconnect path name strings sorted in the same
order as the interconnects property. Consumers drivers will use
interconnect-names to match interconnect paths with interconnect
specifier pairs.
Example:
sdhci@7864000 {
...
interconnects = <&pnoc MASTER_SDCC_1 &bimc SLAVE_EBI_CH0>;
interconnect-names = "sdhc-mem";
};
Qualcomm SDM845 Network-On-Chip interconnect driver binding
-----------------------------------------------------------
SDM845 interconnect providers support system bandwidth requirements through
RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is
able to communicate with the BCM through the Resource State Coordinator (RSC)
associated with each execution environment. Provider nodes must reside within
an RPMh device node pertaining to their RSC and each provider maps to a single
RPMh resource.
Required properties :
- compatible : shall contain only one of the following:
"qcom,sdm845-rsc-hlos"
- #interconnect-cells : should contain 1
Examples:
apps_rsc: rsc {
rsc_hlos: interconnect {
compatible = "qcom,sdm845-rsc-hlos";
#interconnect-cells = <1>;
};
};
Qualcomm Technologies, Inc. FastRPC Driver
The FastRPC implements an IPC (Inter-Processor Communication)
mechanism that allows for clients to transparently make remote method
invocations across DSP and APPS boundaries. This enables developers
to offload tasks to the DSP and free up the application processor for
other tasks.
- compatible:
Usage: required
Value type: <stringlist>
Definition: must be "qcom,fastrpc"
- label
Usage: required
Value type: <string>
Definition: should specify the dsp domain name this fastrpc
corresponds to. must be one of this: "adsp", "mdsp", "sdsp", "cdsp"
- #address-cells
Usage: required
Value type: <u32>
Definition: Must be 1
- #size-cells
Usage: required
Value type: <u32>
Definition: Must be 0
= COMPUTE BANKS
Each subnode of the Fastrpc represents compute context banks available
on the dsp.
- All Compute context banks MUST contain the following properties:
- compatible:
Usage: required
Value type: <stringlist>
Definition: must be "qcom,fastrpc-compute-cb"
- reg
Usage: required
Value type: <u32>
Definition: Context Bank ID.
- qcom,nsessions:
Usage: Optional
Value type: <u32>
Defination: A value indicating how many sessions can share this
context bank. Defaults to 1 when this property
is not specified.
Example:
adsp-pil {
compatible = "qcom,msm8996-adsp-pil";
...
smd-edge {
label = "lpass";
fastrpc {
compatible = "qcom,fastrpc";
qcom,smd-channels = "fastrpcsmd-apps-dsp";
label = "adsp";
#address-cells = <1>;
#size-cells = <0>;
cb@1 {
compatible = "qcom,fastrpc-compute-cb";
reg = <1>;
};
cb@2 {
compatible = "qcom,fastrpc-compute-cb";
reg = <2>;
};
...
};
};
};
Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
This binding represents the on-chip eFuse OTP controller found on
i.MX6Q/D, i.MX6DL/S, i.MX6SL, i.MX6SX, i.MX6UL and i.MX6SLL SoCs.
i.MX6Q/D, i.MX6DL/S, i.MX6SL, i.MX6SX, i.MX6UL, i.MX6ULL/ULZ and i.MX6SLL SoCs.
Required properties:
- compatible: should be one of
......@@ -9,8 +9,10 @@ Required properties:
"fsl,imx6sl-ocotp" (i.MX6SL), or
"fsl,imx6sx-ocotp" (i.MX6SX),
"fsl,imx6ul-ocotp" (i.MX6UL),
"fsl,imx6ull-ocotp" (i.MX6ULL/ULZ),
"fsl,imx7d-ocotp" (i.MX7D/S),
"fsl,imx6sll-ocotp" (i.MX6SLL),
"fsl,imx7ulp-ocotp" (i.MX7ULP),
followed by "syscon".
- #address-cells : Should be 1
- #size-cells : Should be 1
......
......@@ -154,6 +154,7 @@ geniatech Geniatech, Inc.
giantec Giantec Semiconductor, Inc.
giantplus Giantplus Technology Co., Ltd.
globalscale Globalscale Technologies, Inc.
globaltop GlobalTop Technology, Inc.
gmt Global Mixed-mode Technology, Inc.
goodix Shenzhen Huiding Technology Co., Ltd.
google Google, Inc.
......
======================================
Component Helper for Aggregate Drivers
======================================
.. kernel-doc:: drivers/base/component.c
:doc: overview
API
===
.. kernel-doc:: include/linux/component.h
:internal:
.. kernel-doc:: drivers/base/component.c
:export:
.. |struct dev_pm_domain| replace:: :c:type:`struct dev_pm_domain <dev_pm_domain>`
.. |struct generic_pm_domain| replace:: :c:type:`struct generic_pm_domain <generic_pm_domain>`
.. _device_link:
============
Device links
============
......
......@@ -22,6 +22,7 @@ available subsections can be seen below.
device_connection
dma-buf
device_link
component
message-based
sound
frame-buffer
......
.. SPDX-License-Identifier: GPL-2.0
=====================================
GENERIC SYSTEM INTERCONNECT SUBSYSTEM
=====================================
Introduction
------------
This framework is designed to provide a standard kernel interface to control
the settings of the interconnects on an SoC. These settings can be throughput,
latency and priority between multiple interconnected devices or functional
blocks. This can be controlled dynamically in order to save power or provide
maximum performance.
The interconnect bus is hardware with configurable parameters, which can be
set on a data path according to the requests received from various drivers.
An example of interconnect buses are the interconnects between various
components or functional blocks in chipsets. There can be multiple interconnects
on an SoC that can be multi-tiered.
Below is a simplified diagram of a real-world SoC interconnect bus topology.
::
+----------------+ +----------------+
| HW Accelerator |--->| M NoC |<---------------+
+----------------+ +----------------+ |
| | +------------+
+-----+ +-------------+ V +------+ | |
| DDR | | +--------+ | PCIe | | |
+-----+ | | Slaves | +------+ | |
^ ^ | +--------+ | | C NoC |
| | V V | |
+------------------+ +------------------------+ | | +-----+
| |-->| |-->| |-->| CPU |
| |-->| |<--| | +-----+
| Mem NoC | | S NoC | +------------+
| |<--| |---------+ |
| |<--| |<------+ | | +--------+
+------------------+ +------------------------+ | | +-->| Slaves |
^ ^ ^ ^ ^ | | +--------+
| | | | | | V
+------+ | +-----+ +-----+ +---------+ +----------------+ +--------+
| CPUs | | | GPU | | DSP | | Masters |-->| P NoC |-->| Slaves |
+------+ | +-----+ +-----+ +---------+ +----------------+ +--------+
|
+-------+
| Modem |
+-------+
Terminology
-----------
Interconnect provider is the software definition of the interconnect hardware.
The interconnect providers on the above diagram are M NoC, S NoC, C NoC, P NoC
and Mem NoC.
Interconnect node is the software definition of the interconnect hardware
port. Each interconnect provider consists of multiple interconnect nodes,
which are connected to other SoC components including other interconnect
providers. The point on the diagram where the CPUs connect to the memory is
called an interconnect node, which belongs to the Mem NoC interconnect provider.
Interconnect endpoints are the first or the last element of the path. Every
endpoint is a node, but not every node is an endpoint.
Interconnect path is everything between two endpoints including all the nodes
that have to be traversed to reach from a source to destination node. It may
include multiple master-slave pairs across several interconnect providers.
Interconnect consumers are the entities which make use of the data paths exposed
by the providers. The consumers send requests to providers requesting various
throughput, latency and priority. Usually the consumers are device drivers, that
send request based on their needs. An example for a consumer is a video decoder
that supports various formats and image sizes.
Interconnect providers
----------------------
Interconnect provider is an entity that implements methods to initialize and
configure interconnect bus hardware. The interconnect provider drivers should
be registered with the interconnect provider core.
.. kernel-doc:: include/linux/interconnect-provider.h
Interconnect consumers
----------------------
Interconnect consumers are the clients which use the interconnect APIs to
get paths between endpoints and set their bandwidth/latency/QoS requirements
for these interconnect paths.
.. kernel-doc:: include/linux/interconnect.h
......@@ -6699,6 +6699,15 @@ F: drivers/clocksource/h8300_*.c
F: drivers/clk/h8300/
F: drivers/irqchip/irq-renesas-h8*.c
HABANALABS PCI DRIVER
M: Oded Gabbay <oded.gabbay@gmail.com>
T: git https://github.com/HabanaAI/linux.git
S: Supported
F: drivers/misc/habanalabs/
F: include/uapi/misc/habanalabs.h
F: Documentation/ABI/testing/sysfs-driver-habanalabs
F: Documentation/ABI/testing/debugfs-driver-habanalabs
HACKRF MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
......@@ -7056,7 +7065,7 @@ M: Haiyang Zhang <haiyangz@microsoft.com>
M: Stephen Hemminger <sthemmin@microsoft.com>
M: Sasha Levin <sashal@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
L: devel@linuxdriverproject.org
L: linux-hyperv@vger.kernel.org
S: Supported
F: Documentation/networking/device_drivers/microsoft/netvsc.txt
F: arch/x86/include/asm/mshyperv.h
......@@ -7941,6 +7950,16 @@ L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-intel-mid.c
INTERCONNECT API
M: Georgi Djakov <georgi.djakov@linaro.org>
S: Maintained
F: Documentation/interconnect/
F: Documentation/devicetree/bindings/interconnect/
F: drivers/interconnect/
F: include/dt-bindings/interconnect/
F: include/linux/interconnect-provider.h
F: include/linux/interconnect.h
INVENSENSE MPU-3050 GYROSCOPE DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-iio@vger.kernel.org
......
......@@ -711,6 +711,9 @@ config HAVE_ARCH_HASH
file which provides platform-specific implementations of some
functions in <linux/hash.h> or fs/namei.c.
config HAVE_ARCH_NVRAM_OPS
bool
config ISA_BUS_API
def_bool ISA
......
......@@ -16,6 +16,7 @@ config ATARI
bool "Atari support"
depends on MMU
select MMU_MOTOROLA if MMU
select HAVE_ARCH_NVRAM_OPS
help
This option enables support for the 68000-based Atari series of
computers (including the TT, Falcon and Medusa). If you plan to use
......@@ -26,6 +27,7 @@ config MAC
bool "Macintosh support"
depends on MMU
select MMU_MOTOROLA if MMU
select HAVE_ARCH_NVRAM_OPS
help
This option enables support for the Apple Macintosh series of
computers (yes, there is experimental support now, at least for part
......
......@@ -6,3 +6,5 @@ obj-y := config.o time.o debug.o ataints.o stdma.o \
atasound.o stram.o
obj-$(CONFIG_ATARI_KBD_CORE) += atakeyb.o
obj-$(CONFIG_NVRAM:m=y) += nvram.o
// SPDX-License-Identifier: GPL-2.0+
/*
* CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
* Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
* idea by and with help from Richard Jelinek <rj@suse.de>
* Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com)
* Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
* Wim Van Sebroeck.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/mc146818rtc.h>
#include <linux/module.h>
#include <linux/nvram.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#define NVRAM_BYTES 50
/* It is worth noting that these functions all access bytes of general
* purpose memory in the NVRAM - that is to say, they all add the
* NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
* know about the RTC cruft.
*/
/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
* rtc_lock held. Due to the index-port/data-port design of the RTC, we
* don't want two different things trying to get to it at once. (e.g. the
* periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
*/
static unsigned char __nvram_read_byte(int i)
{
return CMOS_READ(NVRAM_FIRST_BYTE + i);
}
/* This races nicely with trying to read with checksum checking */
static void __nvram_write_byte(unsigned char c, int i)
{
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
}
/* On Ataris, the checksum is over all bytes except the checksum bytes
* themselves; these are at the very end.
*/
#define ATARI_CKS_RANGE_START 0
#define ATARI_CKS_RANGE_END 47
#define ATARI_CKS_LOC 48
static int __nvram_check_checksum(void)
{
int i;
unsigned char sum = 0;
for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
sum += __nvram_read_byte(i);
return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
(__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
}
static void __nvram_set_checksum(void)
{
int i;
unsigned char sum = 0;
for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
sum += __nvram_read_byte(i);
__nvram_write_byte(~sum, ATARI_CKS_LOC);
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
}
long atari_nvram_set_checksum(void)
{
spin_lock_irq(&rtc_lock);
__nvram_set_checksum();
spin_unlock_irq(&rtc_lock);
return 0;
}
long atari_nvram_initialize(void)
{
loff_t i;
spin_lock_irq(&rtc_lock);
for (i = 0; i < NVRAM_BYTES; ++i)
__nvram_write_byte(0, i);
__nvram_set_checksum();
spin_unlock_irq(&rtc_lock);
return 0;
}
ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
{
char *p = buf;
loff_t i;
spin_lock_irq(&rtc_lock);
if (!__nvram_check_checksum()) {
spin_unlock_irq(&rtc_lock);
return -EIO;
}
for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
*p = __nvram_read_byte(i);
spin_unlock_irq(&rtc_lock);
*ppos = i;
return p - buf;
}
ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
{
char *p = buf;
loff_t i;
spin_lock_irq(&rtc_lock);
if (!__nvram_check_checksum()) {
spin_unlock_irq(&rtc_lock);
return -EIO;
}
for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
__nvram_write_byte(*p, i);
__nvram_set_checksum();
spin_unlock_irq(&rtc_lock);
*ppos = i;
return p - buf;
}
ssize_t atari_nvram_get_size(void)
{
return NVRAM_BYTES;
}
#ifdef CONFIG_PROC_FS
static struct {
unsigned char val;
const char *name;
} boot_prefs[] = {
{ 0x80, "TOS" },
{ 0x40, "ASV" },
{ 0x20, "NetBSD (?)" },
{ 0x10, "Linux" },
{ 0x00, "unspecified" },
};
static const char * const languages[] = {
"English (US)",
"German",
"French",
"English (UK)",
"Spanish",
"Italian",
"6 (undefined)",
"Swiss (French)",
"Swiss (German)",
};
static const char * const dateformat[] = {
"MM%cDD%cYY",
"DD%cMM%cYY",
"YY%cMM%cDD",
"YY%cDD%cMM",
"4 (undefined)",
"5 (undefined)",
"6 (undefined)",
"7 (undefined)",
};
static const char * const colors[] = {
"2", "4", "16", "256", "65536", "??", "??", "??"
};
static void atari_nvram_proc_read(unsigned char *nvram, struct seq_file *seq,
void *offset)
{
int checksum;
int i;
unsigned int vmode;
spin_lock_irq(&rtc_lock);
checksum = __nvram_check_checksum();
spin_unlock_irq(&rtc_lock);
seq_printf(seq, "Checksum status : %svalid\n", checksum ? "" : "not ");
seq_puts(seq, "Boot preference : ");
for (i = ARRAY_SIZE(boot_prefs) - 1; i >= 0; --i)
if (nvram[1] == boot_prefs[i].val) {
seq_printf(seq, "%s\n", boot_prefs[i].name);
break;
}
if (i < 0)
seq_printf(seq, "0x%02x (undefined)\n", nvram[1]);
seq_printf(seq, "SCSI arbitration : %s\n",
(nvram[16] & 0x80) ? "on" : "off");
seq_puts(seq, "SCSI host ID : ");
if (nvram[16] & 0x80)
seq_printf(seq, "%d\n", nvram[16] & 7);
else
seq_puts(seq, "n/a\n");
if (!MACH_IS_FALCON)
return;
seq_puts(seq, "OS language : ");
if (nvram[6] < ARRAY_SIZE(languages))
seq_printf(seq, "%s\n", languages[nvram[6]]);
else
seq_printf(seq, "%u (undefined)\n", nvram[6]);
seq_puts(seq, "Keyboard language: ");
if (nvram[7] < ARRAY_SIZE(languages))
seq_printf(seq, "%s\n", languages[nvram[7]]);
else
seq_printf(seq, "%u (undefined)\n", nvram[7]);
seq_puts(seq, "Date format : ");
seq_printf(seq, dateformat[nvram[8] & 7],
nvram[9] ? nvram[9] : '/', nvram[9] ? nvram[9] : '/');
seq_printf(seq, ", %dh clock\n", nvram[8] & 16 ? 24 : 12);
seq_puts(seq, "Boot delay : ");
if (nvram[10] == 0)
seq_puts(seq, "default\n");
else
seq_printf(seq, "%ds%s\n", nvram[10],
nvram[10] < 8 ? ", no memory test" : "");
vmode = (nvram[14] << 8) | nvram[15];
seq_printf(seq,
"Video mode : %s colors, %d columns, %s %s monitor\n",
colors[vmode & 7], vmode & 8 ? 80 : 40,
vmode & 16 ? "VGA" : "TV", vmode & 32 ? "PAL" : "NTSC");
seq_printf(seq,
" %soverscan, compat. mode %s%s\n",
vmode & 64 ? "" : "no ", vmode & 128 ? "on" : "off",
vmode & 256 ?
(vmode & 16 ? ", line doubling" : ", half screen") : "");
}
static int nvram_proc_read(struct seq_file *seq, void *offset)
{
unsigned char contents[NVRAM_BYTES];
int i;
spin_lock_irq(&rtc_lock);
for (i = 0; i < NVRAM_BYTES; ++i)
contents[i] = __nvram_read_byte(i);
spin_unlock_irq(&rtc_lock);
atari_nvram_proc_read(contents, seq, offset);
return 0;
}
static int __init atari_nvram_init(void)
{
if (!(MACH_IS_ATARI && ATARIHW_PRESENT(TT_CLK)))
return -ENODEV;
if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
return -ENOMEM;
}
return 0;
}
device_initcall(atari_nvram_init);
#endif /* CONFIG_PROC_FS */
......@@ -33,6 +33,12 @@ extern int atari_dont_touch_floppy_select;
extern int atari_SCC_reset_done;
extern ssize_t atari_nvram_read(char *, size_t, loff_t *);
extern ssize_t atari_nvram_write(char *, size_t, loff_t *);
extern ssize_t atari_nvram_get_size(void);
extern long atari_nvram_set_checksum(void);
extern long atari_nvram_initialize(void);
/* convenience macros for testing machine type */
#define MACH_IS_ST ((atari_mch_cookie >> 16) == ATARI_MCH_ST)
#define MACH_IS_STE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \
......
......@@ -19,6 +19,10 @@ extern void mac_init_IRQ(void);
extern void mac_irq_enable(struct irq_data *data);
extern void mac_irq_disable(struct irq_data *data);
extern unsigned char mac_pram_read_byte(int);
extern void mac_pram_write_byte(unsigned char, int);
extern ssize_t mac_pram_get_size(void);
/*
* Macintosh Table
*/
......
......@@ -24,6 +24,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/module.h>
#include <linux/nvram.h>
#include <linux/initrd.h>
#include <asm/bootinfo.h>
......@@ -37,13 +38,14 @@
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
#endif
#ifdef CONFIG_ATARI
#include <asm/atarihw.h>
#ifdef CONFIG_ATARI
#include <asm/atari_stram.h>
#endif
#ifdef CONFIG_SUN3X
#include <asm/dvma.h>
#endif
#include <asm/macintosh.h>
#include <asm/natfeat.h>
#if !FPSTATESIZE || !NR_IRQS
......@@ -547,3 +549,81 @@ static int __init adb_probe_sync_enable (char *str) {
__setup("adb_sync", adb_probe_sync_enable);
#endif /* CONFIG_ADB */
#if IS_ENABLED(CONFIG_NVRAM)
#ifdef CONFIG_MAC
static unsigned char m68k_nvram_read_byte(int addr)
{
if (MACH_IS_MAC)
return mac_pram_read_byte(addr);
return 0xff;
}
static void m68k_nvram_write_byte(unsigned char val, int addr)
{
if (MACH_IS_MAC)
mac_pram_write_byte(val, addr);
}
#endif /* CONFIG_MAC */
#ifdef CONFIG_ATARI
static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
{
if (MACH_IS_ATARI)
return atari_nvram_read(buf, count, ppos);
else if (MACH_IS_MAC)
return nvram_read_bytes(buf, count, ppos);
return -EINVAL;
}
static ssize_t m68k_nvram_write(char *buf, size_t count, loff_t *ppos)
{
if (MACH_IS_ATARI)
return atari_nvram_write(buf, count, ppos);
else if (MACH_IS_MAC)
return nvram_write_bytes(buf, count, ppos);
return -EINVAL;
}
static long m68k_nvram_set_checksum(void)
{
if (MACH_IS_ATARI)
return atari_nvram_set_checksum();
return -EINVAL;
}
static long m68k_nvram_initialize(void)
{
if (MACH_IS_ATARI)
return atari_nvram_initialize();
return -EINVAL;
}
#endif /* CONFIG_ATARI */
static ssize_t m68k_nvram_get_size(void)
{
if (MACH_IS_ATARI)
return atari_nvram_get_size();
else if (MACH_IS_MAC)
return mac_pram_get_size();
return -ENODEV;
}
/* Atari device drivers call .read (to get checksum validation) whereas
* Mac and PowerMac device drivers just use .read_byte.
*/
const struct nvram_ops arch_nvram_ops = {
#ifdef CONFIG_MAC
.read_byte = m68k_nvram_read_byte,
.write_byte = m68k_nvram_write_byte,
#endif
#ifdef CONFIG_ATARI
.read = m68k_nvram_read,
.write = m68k_nvram_write,
.set_checksum = m68k_nvram_set_checksum,
.initialize = m68k_nvram_initialize,
#endif
.get_size = m68k_nvram_get_size,
};
EXPORT_SYMBOL(arch_nvram_ops);
#endif /* CONFIG_NVRAM */
......@@ -36,8 +36,9 @@
static void (*rom_reset)(void);
#if IS_ENABLED(CONFIG_NVRAM)
#ifdef CONFIG_ADB_CUDA
static __u8 cuda_read_pram(int offset)
static unsigned char cuda_pram_read_byte(int offset)
{
struct adb_request req;
......@@ -49,7 +50,7 @@ static __u8 cuda_read_pram(int offset)
return req.reply[3];
}
static void cuda_write_pram(int offset, __u8 data)
static void cuda_pram_write_byte(unsigned char data, int offset)
{
struct adb_request req;
......@@ -62,29 +63,29 @@ static void cuda_write_pram(int offset, __u8 data)
#endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_ADB_PMU
static __u8 pmu_read_pram(int offset)
static unsigned char pmu_pram_read_byte(int offset)
{
struct adb_request req;
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
(offset >> 8) & 0xFF, offset & 0xFF) < 0)
if (pmu_request(&req, NULL, 3, PMU_READ_XPRAM,
offset & 0xFF, 1) < 0)
return 0;
while (!req.complete)
pmu_poll();
return req.reply[3];
pmu_wait_complete(&req);
return req.reply[0];
}
static void pmu_write_pram(int offset, __u8 data)
static void pmu_pram_write_byte(unsigned char data, int offset)
{
struct adb_request req;
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
(offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
if (pmu_request(&req, NULL, 4, PMU_WRITE_XPRAM,
offset & 0xFF, 1, data) < 0)
return;
while (!req.complete)
pmu_poll();
pmu_wait_complete(&req);
}
#endif /* CONFIG_ADB_PMU */
#endif /* CONFIG_NVRAM */
/*
* VIA PRAM/RTC access routines
......@@ -93,7 +94,7 @@ static void pmu_write_pram(int offset, __u8 data)
* the RTC should be enabled.
*/
static __u8 via_pram_readbyte(void)
static __u8 via_rtc_recv(void)
{
int i, reg;
__u8 data;
......@@ -120,7 +121,7 @@ static __u8 via_pram_readbyte(void)
return data;
}
static void via_pram_writebyte(__u8 data)
static void via_rtc_send(__u8 data)
{
int i, reg, bit;
......@@ -136,6 +137,31 @@ static void via_pram_writebyte(__u8 data)
}
}
/*
* These values can be found in Inside Macintosh vol. III ch. 2
* which has a description of the RTC chip in the original Mac.
*/
#define RTC_FLG_READ BIT(7)
#define RTC_FLG_WRITE_PROTECT BIT(7)
#define RTC_CMD_READ(r) (RTC_FLG_READ | (r << 2))
#define RTC_CMD_WRITE(r) (r << 2)
#define RTC_REG_SECONDS_0 0
#define RTC_REG_SECONDS_1 1
#define RTC_REG_SECONDS_2 2
#define RTC_REG_SECONDS_3 3
#define RTC_REG_WRITE_PROTECT 13
/*
* Inside Mac has no information about two-byte RTC commands but
* the MAME/MESS source code has the essentials.
*/
#define RTC_REG_XPRAM 14
#define RTC_CMD_XPRAM_READ (RTC_CMD_READ(RTC_REG_XPRAM) << 8)
#define RTC_CMD_XPRAM_WRITE (RTC_CMD_WRITE(RTC_REG_XPRAM) << 8)
#define RTC_CMD_XPRAM_ARG(a) (((a & 0xE0) << 3) | ((a & 0x1F) << 2))
/*
* Execute a VIA PRAM/RTC command. For read commands
* data should point to a one-byte buffer for the
......@@ -145,29 +171,33 @@ static void via_pram_writebyte(__u8 data)
* This function disables all interrupts while running.
*/
static void via_pram_command(int command, __u8 *data)
static void via_rtc_command(int command, __u8 *data)
{
unsigned long flags;
int is_read;
local_irq_save(flags);
/* The least significant bits must be 0b01 according to Inside Mac */
command = (command & ~3) | 1;
/* Enable the RTC and make sure the strobe line is high */
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
if (command & 0xFF00) { /* extended (two-byte) command */
via_pram_writebyte((command & 0xFF00) >> 8);
via_pram_writebyte(command & 0xFF);
is_read = command & 0x8000;
via_rtc_send((command & 0xFF00) >> 8);
via_rtc_send(command & 0xFF);
is_read = command & (RTC_FLG_READ << 8);
} else { /* one-byte command */
via_pram_writebyte(command);
is_read = command & 0x80;
via_rtc_send(command);
is_read = command & RTC_FLG_READ;
}
if (is_read) {
*data = via_pram_readbyte();
*data = via_rtc_recv();
} else {
via_pram_writebyte(*data);
via_rtc_send(*data);
}
/* All done, disable the RTC */
......@@ -177,14 +207,30 @@ static void via_pram_command(int command, __u8 *data)
local_irq_restore(flags);
}
static __u8 via_read_pram(int offset)
#if IS_ENABLED(CONFIG_NVRAM)
static unsigned char via_pram_read_byte(int offset)
{
return 0;
unsigned char temp;
via_rtc_command(RTC_CMD_XPRAM_READ | RTC_CMD_XPRAM_ARG(offset), &temp);
return temp;
}
static void via_write_pram(int offset, __u8 data)
static void via_pram_write_byte(unsigned char data, int offset)
{
unsigned char temp;
temp = 0x55;
via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
temp = data;
via_rtc_command(RTC_CMD_XPRAM_WRITE | RTC_CMD_XPRAM_ARG(offset), &temp);
temp = 0x55 | RTC_FLG_WRITE_PROTECT;
via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
}
#endif /* CONFIG_NVRAM */
/*
* Return the current time in seconds since January 1, 1904.
......@@ -201,10 +247,10 @@ static time64_t via_read_time(void)
} result, last_result;
int count = 1;
via_pram_command(0x81, &last_result.cdata[3]);
via_pram_command(0x85, &last_result.cdata[2]);
via_pram_command(0x89, &last_result.cdata[1]);
via_pram_command(0x8D, &last_result.cdata[0]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0), &last_result.cdata[3]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1), &last_result.cdata[2]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2), &last_result.cdata[1]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3), &last_result.cdata[0]);
/*
* The NetBSD guys say to loop until you get the same reading
......@@ -212,10 +258,14 @@ static time64_t via_read_time(void)
*/
while (1) {
via_pram_command(0x81, &result.cdata[3]);
via_pram_command(0x85, &result.cdata[2]);
via_pram_command(0x89, &result.cdata[1]);
via_pram_command(0x8D, &result.cdata[0]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0),
&result.cdata[3]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1),
&result.cdata[2]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2),
&result.cdata[1]);
via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3),
&result.cdata[0]);
if (result.idata == last_result.idata)
return (time64_t)result.idata - RTC_OFFSET;
......@@ -254,18 +304,18 @@ static void via_set_rtc_time(struct rtc_time *tm)
/* Clear the write protect bit */
temp = 0x55;
via_pram_command(0x35, &temp);
via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
data.idata = lower_32_bits(time + RTC_OFFSET);
via_pram_command(0x01, &data.cdata[3]);
via_pram_command(0x05, &data.cdata[2]);
via_pram_command(0x09, &data.cdata[1]);
via_pram_command(0x0D, &data.cdata[0]);
via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_0), &data.cdata[3]);
via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_1), &data.cdata[2]);
via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_2), &data.cdata[1]);
via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_3), &data.cdata[0]);
/* Set the write protect bit */
temp = 0xD5;
via_pram_command(0x35, &temp);
temp = 0x55 | RTC_FLG_WRITE_PROTECT;
via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), &temp);
}
static void via_shutdown(void)
......@@ -326,66 +376,58 @@ static void cuda_shutdown(void)
*-------------------------------------------------------------------
*/
void mac_pram_read(int offset, __u8 *buffer, int len)
#if IS_ENABLED(CONFIG_NVRAM)
unsigned char mac_pram_read_byte(int addr)
{
__u8 (*func)(int);
int i;
switch (macintosh_config->adb_type) {
case MAC_ADB_IOP:
case MAC_ADB_II:
case MAC_ADB_PB1:
func = via_read_pram;
break;
return via_pram_read_byte(addr);
#ifdef CONFIG_ADB_CUDA
case MAC_ADB_EGRET:
case MAC_ADB_CUDA:
func = cuda_read_pram;
break;
return cuda_pram_read_byte(addr);
#endif
#ifdef CONFIG_ADB_PMU
case MAC_ADB_PB2:
func = pmu_read_pram;
break;
return pmu_pram_read_byte(addr);
#endif
default:
return;
}
for (i = 0 ; i < len ; i++) {
buffer[i] = (*func)(offset++);
return 0xFF;
}
}
void mac_pram_write(int offset, __u8 *buffer, int len)
void mac_pram_write_byte(unsigned char val, int addr)
{
void (*func)(int, __u8);
int i;
switch (macintosh_config->adb_type) {
case MAC_ADB_IOP:
case MAC_ADB_II:
case MAC_ADB_PB1:
func = via_write_pram;
via_pram_write_byte(val, addr);
break;
#ifdef CONFIG_ADB_CUDA
case MAC_ADB_EGRET:
case MAC_ADB_CUDA:
func = cuda_write_pram;
cuda_pram_write_byte(val, addr);
break;
#endif
#ifdef CONFIG_ADB_PMU
case MAC_ADB_PB2:
func = pmu_write_pram;
pmu_pram_write_byte(val, addr);
break;
#endif
default:
return;
}
for (i = 0 ; i < len ; i++) {
(*func)(offset++, buffer[i]);
break;
}
}
ssize_t mac_pram_get_size(void)
{
return 256;
}
#endif /* CONFIG_NVRAM */
void mac_poweroff(void)
{
if (oss_present) {
......
......@@ -311,6 +311,15 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
* value for either 32 or 64 bit mode */
#define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL)))
#define ioread64 ioread64
#define ioread64be ioread64be
#define iowrite64 iowrite64
#define iowrite64be iowrite64be
extern u64 ioread64(void __iomem *addr);
extern u64 ioread64be(void __iomem *addr);
extern void iowrite64(u64 val, void __iomem *addr);
extern void iowrite64be(u64 val, void __iomem *addr);
#include <asm-generic/iomap.h>
/*
......
......@@ -48,11 +48,15 @@ struct iomap_ops {
unsigned int (*read16be)(void __iomem *);
unsigned int (*read32)(void __iomem *);
unsigned int (*read32be)(void __iomem *);
u64 (*read64)(void __iomem *);
u64 (*read64be)(void __iomem *);
void (*write8)(u8, void __iomem *);
void (*write16)(u16, void __iomem *);
void (*write16be)(u16, void __iomem *);
void (*write32)(u32, void __iomem *);
void (*write32be)(u32, void __iomem *);
void (*write64)(u64, void __iomem *);
void (*write64be)(u64, void __iomem *);
void (*read8r)(void __iomem *, void *, unsigned long);
void (*read16r)(void __iomem *, void *, unsigned long);
void (*read32r)(void __iomem *, void *, unsigned long);
......@@ -171,6 +175,16 @@ static unsigned int iomem_read32be(void __iomem *addr)
return __raw_readl(addr);
}
static u64 iomem_read64(void __iomem *addr)
{
return readq(addr);
}
static u64 iomem_read64be(void __iomem *addr)
{
return __raw_readq(addr);
}
static void iomem_write8(u8 datum, void __iomem *addr)
{
writeb(datum, addr);
......@@ -196,6 +210,16 @@ static void iomem_write32be(u32 datum, void __iomem *addr)
__raw_writel(datum, addr);
}
static void iomem_write64(u64 datum, void __iomem *addr)
{
writel(datum, addr);
}
static void iomem_write64be(u64 datum, void __iomem *addr)
{
__raw_writel(datum, addr);
}
static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
{
while (count--) {
......@@ -250,11 +274,15 @@ static const struct iomap_ops iomem_ops = {
.read16be = iomem_read16be,
.read32 = iomem_read32,
.read32be = iomem_read32be,
.read64 = iomem_read64,
.read64be = iomem_read64be,
.write8 = iomem_write8,
.write16 = iomem_write16,
.write16be = iomem_write16be,
.write32 = iomem_write32,
.write32be = iomem_write32be,
.write64 = iomem_write64,
.write64be = iomem_write64be,
.read8r = iomem_read8r,
.read16r = iomem_read16r,
.read32r = iomem_read32r,
......@@ -304,6 +332,20 @@ unsigned int ioread32be(void __iomem *addr)
return *((u32 *)addr);
}
u64 ioread64(void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr)))
return iomap_ops[ADDR_TO_REGION(addr)]->read64(addr);
return le64_to_cpup((u64 *)addr);
}
u64 ioread64be(void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr)))
return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr);
return *((u64 *)addr);
}
void iowrite8(u8 datum, void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr))) {
......@@ -349,6 +391,24 @@ void iowrite32be(u32 datum, void __iomem *addr)
}
}
void iowrite64(u64 datum, void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr))) {
iomap_ops[ADDR_TO_REGION(addr)]->write64(datum, addr);
} else {
*((u64 *)addr) = cpu_to_le64(datum);
}
}
void iowrite64be(u64 datum, void __iomem *addr)
{
if (unlikely(INDIRECT_ADDR(addr))) {
iomap_ops[ADDR_TO_REGION(addr)]->write64be(datum, addr);
} else {
*((u64 *)addr) = datum;
}
}
/* Repeating interfaces */
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
......@@ -449,11 +509,15 @@ EXPORT_SYMBOL(ioread16);
EXPORT_SYMBOL(ioread16be);
EXPORT_SYMBOL(ioread32);
EXPORT_SYMBOL(ioread32be);
EXPORT_SYMBOL(ioread64);
EXPORT_SYMBOL(ioread64be);
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
EXPORT_SYMBOL(iowrite16be);
EXPORT_SYMBOL(iowrite32);
EXPORT_SYMBOL(iowrite32be);
EXPORT_SYMBOL(iowrite64);
EXPORT_SYMBOL(iowrite64be);
EXPORT_SYMBOL(ioread8_rep);
EXPORT_SYMBOL(ioread16_rep);
EXPORT_SYMBOL(ioread32_rep);
......
......@@ -179,6 +179,7 @@ config PPC
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_NVRAM_OPS
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_CBPF_JIT if !PPC64
......@@ -275,11 +276,6 @@ config SYSVIPC_COMPAT
depends on COMPAT && SYSVIPC
default y
# All PPC32s use generic nvram driver through ppc_md
config GENERIC_NVRAM
bool
default y if PPC32
config SCHED_OMIT_FRAME_POINTER
bool
default y
......
......@@ -783,8 +783,10 @@ extern void __iounmap_at(void *ea, unsigned long size);
#define mmio_read16be(addr) readw_be(addr)
#define mmio_read32be(addr) readl_be(addr)
#define mmio_read64be(addr) readq_be(addr)
#define mmio_write16be(val, addr) writew_be(val, addr)
#define mmio_write32be(val, addr) writel_be(val, addr)
#define mmio_write64be(val, addr) writeq_be(val, addr)
#define mmio_insb(addr, dst, count) readsb(addr, dst, count)
#define mmio_insw(addr, dst, count) readsw(addr, dst, count)
#define mmio_insl(addr, dst, count) readsl(addr, dst, count)
......
......@@ -78,9 +78,6 @@ extern int pmac_get_partition(int partition);
extern u8 pmac_xpram_read(int xpaddr);
extern void pmac_xpram_write(int xpaddr, u8 data);
/* Synchronize NVRAM */
extern void nvram_sync(void);
/* Initialize NVRAM OS partition */
extern int __init nvram_init_os_partition(struct nvram_os_partition *part);
......@@ -98,10 +95,4 @@ extern int nvram_write_os_partition(struct nvram_os_partition *part,
unsigned int err_type,
unsigned int error_log_cnt);
/* Determine NVRAM size */
extern ssize_t nvram_get_size(void);
/* Normal access to NVRAM */
extern unsigned char nvram_read_byte(int i);
extern void nvram_write_byte(unsigned char c, int i);
#endif /* _ASM_POWERPC_NVRAM_H */
......@@ -7,12 +7,6 @@
* 2 of the License, or (at your option) any later version.
*
* /dev/nvram driver for PPC64
*
* This perhaps should live in drivers/char
*
* TODO: Split the /dev/nvram part (that one can use
* drivers/char/generic_nvram.c) from the arch & partition
* parsing code.
*/
#include <linux/types.h>
......@@ -714,137 +708,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
spin_unlock_irqrestore(&lock, flags);
}
static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
{
if (ppc_md.nvram_size == NULL)
return -ENODEV;
return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
ppc_md.nvram_size());
}
static ssize_t dev_nvram_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t ret;
char *tmp = NULL;
ssize_t size;
if (!ppc_md.nvram_size) {
ret = -ENODEV;
goto out;
}
size = ppc_md.nvram_size();
if (size < 0) {
ret = size;
goto out;
}
if (*ppos >= size) {
ret = 0;
goto out;
}
count = min_t(size_t, count, size - *ppos);
count = min(count, PAGE_SIZE);
tmp = kmalloc(count, GFP_KERNEL);
if (!tmp) {
ret = -ENOMEM;
goto out;
}
ret = ppc_md.nvram_read(tmp, count, ppos);
if (ret <= 0)
goto out;
if (copy_to_user(buf, tmp, ret))
ret = -EFAULT;
out:
kfree(tmp);
return ret;
}
static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t ret;
char *tmp = NULL;
ssize_t size;
ret = -ENODEV;
if (!ppc_md.nvram_size)
goto out;
ret = 0;
size = ppc_md.nvram_size();
if (*ppos >= size || size < 0)
goto out;
count = min_t(size_t, count, size - *ppos);
count = min(count, PAGE_SIZE);
tmp = memdup_user(buf, count);
if (IS_ERR(tmp)) {
ret = PTR_ERR(tmp);
goto out;
}
ret = ppc_md.nvram_write(tmp, count, ppos);
kfree(tmp);
out:
return ret;
}
static long dev_nvram_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
switch(cmd) {
#ifdef CONFIG_PPC_PMAC
case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
printk(KERN_WARNING "nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
/* fall through */
case IOC_NVRAM_GET_OFFSET: {
int part, offset;
if (!machine_is(powermac))
return -EINVAL;
if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
return -EFAULT;
if (part < pmac_nvram_OF || part > pmac_nvram_NR)
return -EINVAL;
offset = pmac_get_partition(part);
if (offset < 0)
return offset;
if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0)
return -EFAULT;
return 0;
}
#endif /* CONFIG_PPC_PMAC */
default:
return -EINVAL;
}
}
static const struct file_operations nvram_fops = {
.owner = THIS_MODULE,
.llseek = dev_nvram_llseek,
.read = dev_nvram_read,
.write = dev_nvram_write,
.unlocked_ioctl = dev_nvram_ioctl,
};
static struct miscdevice nvram_dev = {
NVRAM_MINOR,
"nvram",
&nvram_fops
};
#ifdef DEBUG_NVRAM
static void __init nvram_print_partitions(char * label)
{
......@@ -992,6 +855,8 @@ loff_t __init nvram_create_partition(const char *name, int sig,
long size = 0;
int rc;
BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
/* Convert sizes from bytes to blocks */
req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
......@@ -1192,22 +1057,3 @@ int __init nvram_scan_partitions(void)
kfree(header);
return err;
}
static int __init nvram_init(void)
{
int rc;
BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0)
return -ENODEV;
rc = misc_register(&nvram_dev);
if (rc != 0) {
printk(KERN_ERR "nvram_init: failed to register device\n");
return rc;
}
return rc;
}
device_initcall(nvram_init);
......@@ -17,6 +17,7 @@
#include <linux/console.h>
#include <linux/memblock.h>
#include <linux/export.h>
#include <linux/nvram.h>
#include <asm/io.h>
#include <asm/prom.h>
......@@ -147,41 +148,6 @@ static int __init ppc_setup_l3cr(char *str)
}
__setup("l3cr=", ppc_setup_l3cr);
#ifdef CONFIG_GENERIC_NVRAM
/* Generic nvram hooks used by drivers/char/gen_nvram.c */
unsigned char nvram_read_byte(int addr)
{
if (ppc_md.nvram_read_val)
return ppc_md.nvram_read_val(addr);
return 0xff;
}
EXPORT_SYMBOL(nvram_read_byte);
void nvram_write_byte(unsigned char val, int addr)
{
if (ppc_md.nvram_write_val)
ppc_md.nvram_write_val(addr, val);
}
EXPORT_SYMBOL(nvram_write_byte);
ssize_t nvram_get_size(void)
{
if (ppc_md.nvram_size)
return ppc_md.nvram_size();
return -1;
}
EXPORT_SYMBOL(nvram_get_size);
void nvram_sync(void)
{
if (ppc_md.nvram_sync)
ppc_md.nvram_sync();
}
EXPORT_SYMBOL(nvram_sync);
#endif /* CONFIG_NVRAM */
static int __init ppc_init(void)
{
/* clear the progress line */
......
obj-y += setup.o time.o pegasos_eth.o pci.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_NVRAM) += nvram.o
obj-$(CONFIG_NVRAM:m=y) += nvram.o
......@@ -24,7 +24,7 @@ static unsigned int nvram_size;
static unsigned char nvram_buf[4];
static DEFINE_SPINLOCK(nvram_lock);
static unsigned char chrp_nvram_read(int addr)
static unsigned char chrp_nvram_read_val(int addr)
{
unsigned int done;
unsigned long flags;
......@@ -46,7 +46,7 @@ static unsigned char chrp_nvram_read(int addr)
return ret;
}
static void chrp_nvram_write(int addr, unsigned char val)
static void chrp_nvram_write_val(int addr, unsigned char val)
{
unsigned int done;
unsigned long flags;
......@@ -64,6 +64,11 @@ static void chrp_nvram_write(int addr, unsigned char val)
spin_unlock_irqrestore(&nvram_lock, flags);
}
static ssize_t chrp_nvram_size(void)
{
return nvram_size;
}
void __init chrp_nvram_init(void)
{
struct device_node *nvram;
......@@ -85,8 +90,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
ppc_md.nvram_read_val = chrp_nvram_read;
ppc_md.nvram_write_val = chrp_nvram_write;
ppc_md.nvram_read_val = chrp_nvram_read_val;
ppc_md.nvram_write_val = chrp_nvram_write_val;
ppc_md.nvram_size = chrp_nvram_size;
return;
}
......
......@@ -549,7 +549,7 @@ static void __init chrp_init_IRQ(void)
static void __init
chrp_init2(void)
{
#ifdef CONFIG_NVRAM
#if IS_ENABLED(CONFIG_NVRAM)
chrp_nvram_init();
#endif
......
......@@ -15,7 +15,5 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really
# CONFIG_NVRAM=y
obj-$(CONFIG_NVRAM:m=y) += nvram.o
# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
obj-$(CONFIG_PPC64) += nvram.o
obj-$(CONFIG_PPC32) += bootx_init.o
obj-$(CONFIG_SMP) += smp.o
......@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
static volatile unsigned char __iomem *nvram_addr;
static int nvram_mult;
static ssize_t ppc32_nvram_size(void)
{
return NVRAM_SIZE;
}
static unsigned char direct_nvram_read_byte(int addr)
{
return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
......@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val = direct_nvram_read_byte;
ppc_md.nvram_write_val = direct_nvram_write_byte;
ppc_md.nvram_size = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val = direct_nvram_read_byte;
ppc_md.nvram_write_val = direct_nvram_write_byte;
ppc_md.nvram_size = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val = indirect_nvram_read_byte;
ppc_md.nvram_write_val = indirect_nvram_write_byte;
ppc_md.nvram_size = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
#ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val = pmu_nvram_read_byte;
ppc_md.nvram_write_val = pmu_nvram_write_byte;
ppc_md.nvram_size = ppc32_nvram_size;
#endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");
......
......@@ -316,8 +316,7 @@ static void __init pmac_setup_arch(void)
find_via_pmu();
smu_init();
#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
defined(CONFIG_PPC64)
#if IS_ENABLED(CONFIG_NVRAM)
pmac_nvram_init();
#endif
#ifdef CONFIG_PPC32
......
......@@ -68,7 +68,7 @@
long __init pmac_time_init(void)
{
s32 delta = 0;
#ifdef CONFIG_NVRAM
#if defined(CONFIG_NVRAM) && defined(CONFIG_PPC32)
int dst;
delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
......
......@@ -7,8 +7,6 @@
* 2 of the License, or (at your option) any later version.
*
* /dev/nvram driver for PPC64
*
* This perhaps should live in drivers/char
*/
......
......@@ -228,4 +228,6 @@ source "drivers/siox/Kconfig"
source "drivers/slimbus/Kconfig"
source "drivers/interconnect/Kconfig"
endmenu
......@@ -186,3 +186,4 @@ obj-$(CONFIG_MULTIPLEXER) += mux/
obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/
obj-$(CONFIG_SIOX) += siox/
obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
......@@ -10,7 +10,7 @@ if ANDROID
config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
depends on MMU && !CPU_CACHE_VIVT
depends on MMU
default n
---help---
Binder is used in Android for both communication between processes,
......
This diff is collapsed.
This diff is collapsed.
......@@ -22,6 +22,7 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/list_lru.h>
#include <uapi/linux/android/binder.h>
extern struct list_lru binder_alloc_lru;
struct binder_transaction;
......@@ -39,7 +40,7 @@ struct binder_transaction;
* @data_size: size of @transaction data
* @offsets_size: size of array of offsets
* @extra_buffers_size: size of space for other objects (like sg lists)
* @data: pointer to base of buffer space
* @user_data: user pointer to base of buffer space
*
* Bookkeeping structure for binder transaction buffers
*/
......@@ -58,7 +59,7 @@ struct binder_buffer {
size_t data_size;
size_t offsets_size;
size_t extra_buffers_size;
void *data;
void __user *user_data;
};
/**
......@@ -81,7 +82,6 @@ struct binder_lru_page {
* (invariant after init)
* @vma_vm_mm: copy of vma->vm_mm (invarient after mmap)
* @buffer: base of per-proc address space mapped via mmap
* @user_buffer_offset: offset between user and kernel VAs for buffer
* @buffers: list of all buffers for this proc
* @free_buffers: rb tree of buffers available for allocation
* sorted by size
......@@ -102,8 +102,7 @@ struct binder_alloc {
struct mutex mutex;
struct vm_area_struct *vma;
struct mm_struct *vma_vm_mm;
void *buffer;
ptrdiff_t user_buffer_offset;
void __user *buffer;
struct list_head buffers;
struct rb_root free_buffers;
struct rb_root allocated_buffers;
......@@ -162,26 +161,24 @@ binder_alloc_get_free_async_space(struct binder_alloc *alloc)
return free_async_space;
}
/**
* binder_alloc_get_user_buffer_offset() - get offset between kernel/user addrs
* @alloc: binder_alloc for this proc
*
* Return: the offset between kernel and user-space addresses to use for
* virtual address conversion
*/
static inline ptrdiff_t
binder_alloc_get_user_buffer_offset(struct binder_alloc *alloc)
{
/*
* user_buffer_offset is constant if vma is set and
* undefined if vma is not set. It is possible to
* get here with !alloc->vma if the target process
* is dying while a transaction is being initiated.
* Returning the old value is ok in this case and
* the transaction will fail.
*/
return alloc->user_buffer_offset;
}
unsigned long
binder_alloc_copy_user_to_buffer(struct binder_alloc *alloc,
struct binder_buffer *buffer,
binder_size_t buffer_offset,
const void __user *from,
size_t bytes);
void binder_alloc_copy_to_buffer(struct binder_alloc *alloc,
struct binder_buffer *buffer,
binder_size_t buffer_offset,
void *src,
size_t bytes);
void binder_alloc_copy_from_buffer(struct binder_alloc *alloc,
void *dest,
struct binder_buffer *buffer,
binder_size_t buffer_offset,
size_t bytes);
#endif /* _LINUX_BINDER_ALLOC_H */
......@@ -102,11 +102,12 @@ static bool check_buffer_pages_allocated(struct binder_alloc *alloc,
struct binder_buffer *buffer,
size_t size)
{
void *page_addr, *end;
void __user *page_addr;
void __user *end;
int page_index;
end = (void *)PAGE_ALIGN((uintptr_t)buffer->data + size);
page_addr = buffer->data;
end = (void __user *)PAGE_ALIGN((uintptr_t)buffer->user_data + size);
page_addr = buffer->user_data;
for (; page_addr < end; page_addr += PAGE_SIZE) {
page_index = (page_addr - alloc->buffer) / PAGE_SIZE;
if (!alloc->pages[page_index].page_ptr ||
......
......@@ -293,7 +293,7 @@ DEFINE_EVENT(binder_buffer_class, binder_transaction_failed_buffer_release,
TRACE_EVENT(binder_update_page_range,
TP_PROTO(struct binder_alloc *alloc, bool allocate,
void *start, void *end),
void __user *start, void __user *end),
TP_ARGS(alloc, allocate, start, end),
TP_STRUCT__entry(
__field(int, proc)
......
This diff is collapsed.
......@@ -244,26 +244,23 @@ source "drivers/char/hw_random/Kconfig"
config NVRAM
tristate "/dev/nvram support"
depends on ATARI || X86 || GENERIC_NVRAM
depends on X86 || HAVE_ARCH_NVRAM_OPS
default M68K || PPC
---help---
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
you get read and write access to the extra bytes of non-volatile
memory in the real time clock (RTC), which is contained in every PC
and most Ataris. The actual number of bytes varies, depending on the
nvram in the system, but is usually 114 (128-14 for the RTC).
This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
on Ataris. /dev/nvram may be used to view settings there, or to
change them (with some utility). It could also be used to frequently
you get read and write access to the non-volatile memory.
/dev/nvram may be used to view settings in NVRAM or to change them
(with some utility). It could also be used to frequently
save a few bits of very important data that may not be lost over
power-off and for which writing to disk is too insecure. Note
however that most NVRAM space in a PC belongs to the BIOS and you
should NEVER idly tamper with it. See Ralf Brown's interrupt list
for a guide to the use of CMOS bytes by your BIOS.
On Atari machines, /dev/nvram is always configured and does not need
to be selected.
This memory is conventionally called "NVRAM" on PowerPC machines,
"CMOS RAM" on PCs, "NVRAM" on Ataris and "PRAM" on Macintoshes.
To compile this driver as a module, choose M here: the
module will be called nvram.
......
......@@ -26,11 +26,7 @@ obj-$(CONFIG_RTC) += rtc.o
obj-$(CONFIG_HPET) += hpet.o
obj-$(CONFIG_EFI_RTC) += efirtc.o
obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/
ifeq ($(CONFIG_GENERIC_NVRAM),y)
obj-$(CONFIG_NVRAM) += generic_nvram.o
else
obj-$(CONFIG_NVRAM) += nvram.o
endif
obj-$(CONFIG_NVRAM) += nvram.o
obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_HW_RANDOM) += hw_random/
......
......@@ -32,6 +32,7 @@
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/nospec.h>
#include <asm/io.h>
#include <linux/uaccess.h>
......@@ -386,7 +387,11 @@ static ssize_t ac_write(struct file *file, const char __user *buf, size_t count,
TicCard = st_loc.tic_des_from_pc; /* tic number to send */
IndexCard = NumCard - 1;
if((NumCard < 1) || (NumCard > MAX_BOARD) || !apbs[IndexCard].RamIO)
if (IndexCard >= MAX_BOARD)
return -EINVAL;
IndexCard = array_index_nospec(IndexCard, MAX_BOARD);
if (!apbs[IndexCard].RamIO)
return -EINVAL;
#ifdef DEBUG
......@@ -697,6 +702,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
unsigned char IndexCard;
void __iomem *pmem;
int ret = 0;
static int warncount = 10;
volatile unsigned char byte_reset_it;
struct st_ram_io *adgl;
void __user *argp = (void __user *)arg;
......@@ -711,16 +717,12 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mutex_lock(&ac_mutex);
IndexCard = adgl->num_card-1;
if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
static int warncount = 10;
if (warncount) {
printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1);
warncount--;
}
kfree(adgl);
mutex_unlock(&ac_mutex);
return -EINVAL;
}
if (cmd != 6 && IndexCard >= MAX_BOARD)
goto err;
IndexCard = array_index_nospec(IndexCard, MAX_BOARD);
if (cmd != 6 && !apbs[IndexCard].RamIO)
goto err;
switch (cmd) {
......@@ -838,5 +840,16 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
kfree(adgl);
mutex_unlock(&ac_mutex);
return 0;
err:
if (warncount) {
pr_warn("APPLICOM driver IOCTL, bad board number %d\n",
(int)IndexCard + 1);
warncount--;
}
kfree(adgl);
mutex_unlock(&ac_mutex);
return -EINVAL;
}
......@@ -254,27 +254,6 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd,
return -ENOTTY;
}
/*
* We enforce only one user at a time here with the open/close.
* Also clear the previous interrupt data on an open, and clean
* up things on a close.
*/
static int efi_rtc_open(struct inode *inode, struct file *file)
{
/*
* nothing special to do here
* We do accept multiple open files at the same time as we
* synchronize on the per call operation.
*/
return 0;
}
static int efi_rtc_close(struct inode *inode, struct file *file)
{
return 0;
}
/*
* The various file operations we support.
*/
......@@ -282,8 +261,6 @@ static int efi_rtc_close(struct inode *inode, struct file *file)
static const struct file_operations efi_rtc_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = efi_rtc_ioctl,
.open = efi_rtc_open,
.release = efi_rtc_close,
.llseek = no_llseek,
};
......
/*
* Generic /dev/nvram driver for architectures providing some
* "generic" hooks, that is :
*
* nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
*
* Note that an additional hook is supported for PowerMac only
* for getting the nvram "partition" informations
*
*/
#define NVRAM_VERSION "1.1"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/pagemap.h>
#include <linux/uaccess.h>
#include <asm/nvram.h>
#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
#endif
#define NVRAM_SIZE 8192
static DEFINE_MUTEX(nvram_mutex);
static ssize_t nvram_len;
static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
{
return generic_file_llseek_size(file, offset, origin,
MAX_LFS_FILESIZE, nvram_len);
}
static ssize_t read_nvram(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int i;
char __user *p = buf;
if (!access_ok(buf, count))
return -EFAULT;
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
if (__put_user(nvram_read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
}
static ssize_t write_nvram(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int i;
const char __user *p = buf;
char c;
if (!access_ok(buf, count))
return -EFAULT;
if (*ppos >= nvram_len)
return 0;
for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
nvram_write_byte(c, i);
}
*ppos = i;
return p - buf;
}
static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
#ifdef CONFIG_PPC_PMAC
case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
printk(KERN_WARNING "nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
case IOC_NVRAM_GET_OFFSET: {
int part, offset;
if (!machine_is(powermac))
return -EINVAL;
if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
return -EFAULT;
if (part < pmac_nvram_OF || part > pmac_nvram_NR)
return -EINVAL;
offset = pmac_get_partition(part);
if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0)
return -EFAULT;
break;
}
#endif /* CONFIG_PPC_PMAC */
case IOC_NVRAM_SYNC:
nvram_sync();
break;
default:
return -EINVAL;
}
return 0;
}
static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
mutex_lock(&nvram_mutex);
ret = nvram_ioctl(file, cmd, arg);
mutex_unlock(&nvram_mutex);
return ret;
}
const struct file_operations nvram_fops = {
.owner = THIS_MODULE,
.llseek = nvram_llseek,
.read = read_nvram,
.write = write_nvram,
.unlocked_ioctl = nvram_unlocked_ioctl,
};
static struct miscdevice nvram_dev = {
NVRAM_MINOR,
"nvram",
&nvram_fops
};
int __init nvram_init(void)
{
int ret = 0;
printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
NVRAM_VERSION);
ret = misc_register(&nvram_dev);
if (ret != 0)
goto out;
nvram_len = nvram_get_size();
if (nvram_len < 0)
nvram_len = NVRAM_SIZE;
out:
return ret;
}
void __exit nvram_cleanup(void)
{
misc_deregister( &nvram_dev );
}
module_init(nvram_init);
module_exit(nvram_cleanup);
MODULE_LICENSE("GPL");
......@@ -377,7 +377,7 @@ static __init int hpet_mmap_enable(char *str)
pr_info("HPET mmap %s\n", hpet_mmap_enabled ? "enabled" : "disabled");
return 1;
}
__setup("hpet_mmap", hpet_mmap_enable);
__setup("hpet_mmap=", hpet_mmap_enable);
static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
{
......@@ -842,7 +842,6 @@ int hpet_alloc(struct hpet_data *hdp)
struct hpet_dev *devp;
u32 i, ntimer;
struct hpets *hpetp;
size_t siz;
struct hpet __iomem *hpet;
static struct hpets *last;
unsigned long period;
......@@ -860,10 +859,8 @@ int hpet_alloc(struct hpet_data *hdp)
return 0;
}
siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
sizeof(struct hpet_dev));
hpetp = kzalloc(siz, GFP_KERNEL);
hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs - 1),
GFP_KERNEL);
if (!hpetp)
return -ENOMEM;
......
......@@ -729,7 +729,7 @@ static long lp_ioctl(struct file *file, unsigned int cmd,
ret = lp_set_timeout32(minor, (void __user *)arg);
break;
}
/* fallthrough for 64-bit */
/* fall through - for 64-bit */
case LPSETTIMEOUT_NEW:
ret = lp_set_timeout64(minor, (void __user *)arg);
break;
......@@ -757,7 +757,7 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd,
ret = lp_set_timeout32(minor, (void __user *)arg);
break;
}
/* fallthrough for x32 mode */
/* fall through - for x32 mode */
case LPSETTIMEOUT_NEW:
ret = lp_set_timeout64(minor, (void __user *)arg);
break;
......
......@@ -50,6 +50,7 @@ static LIST_HEAD(soft_list);
* file operations
*/
static const struct file_operations mbcs_ops = {
.owner = THIS_MODULE,
.open = mbcs_open,
.llseek = mbcs_sram_llseek,
.read = mbcs_sram_read,
......
This diff is collapsed.
......@@ -114,6 +114,14 @@ config EXTCON_PALMAS
Say Y here to enable support for USB peripheral and USB host
detection by palmas usb.
config EXTCON_PTN5150
tristate "NXP PTN5150 CC LOGIC USB EXTCON support"
depends on I2C && GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y here to enable support for USB peripheral and USB host
detection by NXP PTN5150 CC (Configuration Channel) logic chip.
config EXTCON_QCOM_SPMI_MISC
tristate "Qualcomm USB extcon support"
depends on ARCH_QCOM || COMPILE_TEST
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o
obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o
obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o
obj-$(CONFIG_EXTCON_PTN5150) += extcon-ptn5150.o
obj-$(CONFIG_EXTCON_QCOM_SPMI_MISC) += extcon-qcom-spmi-misc.o
obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o
obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o
......
// SPDX-License-Identifier: GPL-2.0+
//
// extcon-ptn5150.c - PTN5150 CC logic extcon driver to support USB detection
//
// Based on extcon-sm5502.c driver
// Copyright (c) 2018-2019 by Vijai Kumar K
// Author: Vijai Kumar K <vijaikumar.kanagarajan@gmail.com>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/extcon-provider.h>
#include <linux/gpio/consumer.h>
/* PTN5150 registers */
enum ptn5150_reg {
PTN5150_REG_DEVICE_ID = 0x01,
PTN5150_REG_CONTROL,
PTN5150_REG_INT_STATUS,
PTN5150_REG_CC_STATUS,
PTN5150_REG_CON_DET = 0x09,
PTN5150_REG_VCONN_STATUS,
PTN5150_REG_RESET,
PTN5150_REG_INT_MASK = 0x18,
PTN5150_REG_INT_REG_STATUS,
PTN5150_REG_END,
};
#define PTN5150_DFP_ATTACHED 0x1
#define PTN5150_UFP_ATTACHED 0x2
/* Define PTN5150 MASK/SHIFT constant */
#define PTN5150_REG_DEVICE_ID_VENDOR_SHIFT 0
#define PTN5150_REG_DEVICE_ID_VENDOR_MASK \
(0x3 << PTN5150_REG_DEVICE_ID_VENDOR_SHIFT)
#define PTN5150_REG_DEVICE_ID_VERSION_SHIFT 3
#define PTN5150_REG_DEVICE_ID_VERSION_MASK \
(0x1f << PTN5150_REG_DEVICE_ID_VERSION_SHIFT)
#define PTN5150_REG_CC_PORT_ATTACHMENT_SHIFT 2
#define PTN5150_REG_CC_PORT_ATTACHMENT_MASK \
(0x7 << PTN5150_REG_CC_PORT_ATTACHMENT_SHIFT)
#define PTN5150_REG_CC_VBUS_DETECTION_SHIFT 7
#define PTN5150_REG_CC_VBUS_DETECTION_MASK \
(0x1 << PTN5150_REG_CC_VBUS_DETECTION_SHIFT)
#define PTN5150_REG_INT_CABLE_ATTACH_SHIFT 0
#define PTN5150_REG_INT_CABLE_ATTACH_MASK \
(0x1 << PTN5150_REG_INT_CABLE_ATTACH_SHIFT)
#define PTN5150_REG_INT_CABLE_DETACH_SHIFT 1
#define PTN5150_REG_INT_CABLE_DETACH_MASK \
(0x1 << PTN5150_REG_CC_CABLE_DETACH_SHIFT)
struct ptn5150_info {
struct device *dev;
struct extcon_dev *edev;
struct i2c_client *i2c;
struct regmap *regmap;
struct gpio_desc *int_gpiod;
struct gpio_desc *vbus_gpiod;
int irq;
struct work_struct irq_work;
struct mutex mutex;
};
/* List of detectable cables */
static const unsigned int ptn5150_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
static const struct regmap_config ptn5150_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = PTN5150_REG_END,
};
static void ptn5150_irq_work(struct work_struct *work)
{
struct ptn5150_info *info = container_of(work,
struct ptn5150_info, irq_work);
int ret = 0;
unsigned int reg_data;
unsigned int int_status;
if (!info->edev)
return;
mutex_lock(&info->mutex);
ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, &reg_data);
if (ret) {
dev_err(info->dev, "failed to read CC STATUS %d\n", ret);
mutex_unlock(&info->mutex);
return;
}
/* Clear interrupt. Read would clear the register */
ret = regmap_read(info->regmap, PTN5150_REG_INT_STATUS, &int_status);
if (ret) {
dev_err(info->dev, "failed to read INT STATUS %d\n", ret);
mutex_unlock(&info->mutex);
return;
}
if (int_status) {
unsigned int cable_attach;
cable_attach = int_status & PTN5150_REG_INT_CABLE_ATTACH_MASK;
if (cable_attach) {
unsigned int port_status;
unsigned int vbus;
port_status = ((reg_data &
PTN5150_REG_CC_PORT_ATTACHMENT_MASK) >>
PTN5150_REG_CC_PORT_ATTACHMENT_SHIFT);
switch (port_status) {
case PTN5150_DFP_ATTACHED:
extcon_set_state_sync(info->edev,
EXTCON_USB_HOST, false);
gpiod_set_value(info->vbus_gpiod, 0);
extcon_set_state_sync(info->edev, EXTCON_USB,
true);
break;
case PTN5150_UFP_ATTACHED:
extcon_set_state_sync(info->edev, EXTCON_USB,
false);
vbus = ((reg_data &
PTN5150_REG_CC_VBUS_DETECTION_MASK) >>
PTN5150_REG_CC_VBUS_DETECTION_SHIFT);
if (vbus)
gpiod_set_value(info->vbus_gpiod, 0);
else
gpiod_set_value(info->vbus_gpiod, 1);
extcon_set_state_sync(info->edev,
EXTCON_USB_HOST, true);
break;
default:
dev_err(info->dev,
"Unknown Port status : %x\n",
port_status);
break;
}
} else {
extcon_set_state_sync(info->edev,
EXTCON_USB_HOST, false);
extcon_set_state_sync(info->edev,
EXTCON_USB, false);
gpiod_set_value(info->vbus_gpiod, 0);
}
}
/* Clear interrupt. Read would clear the register */
ret = regmap_read(info->regmap, PTN5150_REG_INT_REG_STATUS,
&int_status);
if (ret) {
dev_err(info->dev,
"failed to read INT REG STATUS %d\n", ret);
mutex_unlock(&info->mutex);
return;
}
mutex_unlock(&info->mutex);
}
static irqreturn_t ptn5150_irq_handler(int irq, void *data)
{
struct ptn5150_info *info = data;
schedule_work(&info->irq_work);
return IRQ_HANDLED;
}
static int ptn5150_init_dev_type(struct ptn5150_info *info)
{
unsigned int reg_data, vendor_id, version_id;
int ret;
ret = regmap_read(info->regmap, PTN5150_REG_DEVICE_ID, &reg_data);
if (ret) {
dev_err(info->dev, "failed to read DEVICE_ID %d\n", ret);
return -EINVAL;
}
vendor_id = ((reg_data & PTN5150_REG_DEVICE_ID_VENDOR_MASK) >>
PTN5150_REG_DEVICE_ID_VENDOR_SHIFT);
version_id = ((reg_data & PTN5150_REG_DEVICE_ID_VERSION_MASK) >>
PTN5150_REG_DEVICE_ID_VERSION_SHIFT);
dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
version_id, vendor_id);
/* Clear any existing interrupts */
ret = regmap_read(info->regmap, PTN5150_REG_INT_STATUS, &reg_data);
if (ret) {
dev_err(info->dev,
"failed to read PTN5150_REG_INT_STATUS %d\n",
ret);
return -EINVAL;
}
ret = regmap_read(info->regmap, PTN5150_REG_INT_REG_STATUS, &reg_data);
if (ret) {
dev_err(info->dev,
"failed to read PTN5150_REG_INT_REG_STATUS %d\n", ret);
return -EINVAL;
}
return 0;
}
static int ptn5150_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct device *dev = &i2c->dev;
struct device_node *np = i2c->dev.of_node;
struct ptn5150_info *info;
int ret;
if (!np)
return -EINVAL;
info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
i2c_set_clientdata(i2c, info);
info->dev = &i2c->dev;
info->i2c = i2c;
info->int_gpiod = devm_gpiod_get(&i2c->dev, "int", GPIOD_IN);
if (IS_ERR(info->int_gpiod)) {
dev_err(dev, "failed to get INT GPIO\n");
return PTR_ERR(info->int_gpiod);
}
info->vbus_gpiod = devm_gpiod_get(&i2c->dev, "vbus", GPIOD_IN);
if (IS_ERR(info->vbus_gpiod)) {
dev_err(dev, "failed to get VBUS GPIO\n");
return PTR_ERR(info->vbus_gpiod);
}
ret = gpiod_direction_output(info->vbus_gpiod, 0);
if (ret) {
dev_err(dev, "failed to set VBUS GPIO direction\n");
return -EINVAL;
}
mutex_init(&info->mutex);
INIT_WORK(&info->irq_work, ptn5150_irq_work);
info->regmap = devm_regmap_init_i2c(i2c, &ptn5150_regmap_config);
if (IS_ERR(info->regmap)) {
ret = PTR_ERR(info->regmap);
dev_err(info->dev, "failed to allocate register map: %d\n",
ret);
return ret;
}
if (info->int_gpiod) {
info->irq = gpiod_to_irq(info->int_gpiod);
if (info->irq < 0) {
dev_err(dev, "failed to get INTB IRQ\n");
return info->irq;
}
ret = devm_request_threaded_irq(dev, info->irq, NULL,
ptn5150_irq_handler,
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
i2c->name, info);
if (ret < 0) {
dev_err(dev, "failed to request handler for INTB IRQ\n");
return ret;
}
}
/* Allocate extcon device */
info->edev = devm_extcon_dev_allocate(info->dev, ptn5150_extcon_cable);
if (IS_ERR(info->edev)) {
dev_err(info->dev, "failed to allocate memory for extcon\n");
return -ENOMEM;
}
/* Register extcon device */
ret = devm_extcon_dev_register(info->dev, info->edev);
if (ret) {
dev_err(info->dev, "failed to register extcon device\n");
return ret;
}
/* Initialize PTN5150 device and print vendor id and version id */
ret = ptn5150_init_dev_type(info);
if (ret)
return -EINVAL;
return 0;
}
static const struct of_device_id ptn5150_dt_match[] = {
{ .compatible = "nxp,ptn5150" },
{ },
};
MODULE_DEVICE_TABLE(of, ptn5150_dt_match);
static const struct i2c_device_id ptn5150_i2c_id[] = {
{ "ptn5150", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ptn5150_i2c_id);
static struct i2c_driver ptn5150_i2c_driver = {
.driver = {
.name = "ptn5150",
.of_match_table = ptn5150_dt_match,
},
.probe = ptn5150_i2c_probe,
.id_table = ptn5150_i2c_id,
};
static int __init ptn5150_i2c_init(void)
{
return i2c_add_driver(&ptn5150_i2c_driver);
}
subsys_initcall(ptn5150_i2c_init);
MODULE_DESCRIPTION("NXP PTN5150 CC logic Extcon driver");
MODULE_AUTHOR("Vijai Kumar K <vijaikumar.kanagarajan@gmail.com>");
MODULE_LICENSE("GPL v2");
......@@ -104,7 +104,7 @@ config SOCFPGA_FPGA_BRIDGE
config ALTERA_FREEZE_BRIDGE
tristate "Altera FPGA Freeze Bridge"
depends on ARCH_SOCFPGA && FPGA_BRIDGE
depends on FPGA_BRIDGE && HAS_IOMEM
help
Say Y to enable drivers for Altera FPGA Freeze bridges. A
freeze bridge is a bridge that exists in the FPGA fabric to
......
......@@ -205,7 +205,7 @@ static int altera_ps_write_complete(struct fpga_manager *mgr,
struct fpga_image_info *info)
{
struct altera_ps_conf *conf = mgr->priv;
const char dummy[] = {0};
static const char dummy[] = {0};
int ret;
if (gpiod_get_value_cansleep(conf->status)) {
......
......@@ -15,6 +15,19 @@ if GNSS
config GNSS_SERIAL
tristate
config GNSS_MTK_SERIAL
tristate "Mediatek GNSS receiver support"
depends on SERIAL_DEV_BUS
select GNSS_SERIAL
help
Say Y here if you have a Mediatek-based GNSS receiver which uses a
serial interface.
To compile this driver as a module, choose M here: the module will
be called gnss-mtk.
If unsure, say N.
config GNSS_SIRF_SERIAL
tristate "SiRFstar GNSS receiver support"
depends on SERIAL_DEV_BUS
......
......@@ -9,6 +9,9 @@ gnss-y := core.o
obj-$(CONFIG_GNSS_SERIAL) += gnss-serial.o
gnss-serial-y := serial.o
obj-$(CONFIG_GNSS_MTK_SERIAL) += gnss-mtk.o
gnss-mtk-y := mtk.o
obj-$(CONFIG_GNSS_SIRF_SERIAL) += gnss-sirf.o
gnss-sirf-y := sirf.o
......
......@@ -334,6 +334,7 @@ static const char * const gnss_type_names[GNSS_TYPE_COUNT] = {
[GNSS_TYPE_NMEA] = "NMEA",
[GNSS_TYPE_SIRF] = "SiRF",
[GNSS_TYPE_UBX] = "UBX",
[GNSS_TYPE_MTK] = "MTK",
};
static const char *gnss_type_name(struct gnss_device *gdev)
......
// SPDX-License-Identifier: GPL-2.0
/*
* Mediatek GNSS receiver driver
*
* Copyright (C) 2018 Johan Hovold <johan@kernel.org>
*/
#include <linux/errno.h>
#include <linux/gnss.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/serdev.h>
#include "serial.h"
struct mtk_data {
struct regulator *vbackup;
struct regulator *vcc;
};
static int mtk_set_active(struct gnss_serial *gserial)
{
struct mtk_data *data = gnss_serial_get_drvdata(gserial);
int ret;
ret = regulator_enable(data->vcc);
if (ret)
return ret;
return 0;
}
static int mtk_set_standby(struct gnss_serial *gserial)
{
struct mtk_data *data = gnss_serial_get_drvdata(gserial);
int ret;
ret = regulator_disable(data->vcc);
if (ret)
return ret;
return 0;
}
static int mtk_set_power(struct gnss_serial *gserial,
enum gnss_serial_pm_state state)
{
switch (state) {
case GNSS_SERIAL_ACTIVE:
return mtk_set_active(gserial);
case GNSS_SERIAL_OFF:
case GNSS_SERIAL_STANDBY:
return mtk_set_standby(gserial);
}
return -EINVAL;
}
static const struct gnss_serial_ops mtk_gserial_ops = {
.set_power = mtk_set_power,
};
static int mtk_probe(struct serdev_device *serdev)
{
struct gnss_serial *gserial;
struct mtk_data *data;
int ret;
gserial = gnss_serial_allocate(serdev, sizeof(*data));
if (IS_ERR(gserial)) {
ret = PTR_ERR(gserial);
return ret;
}
gserial->ops = &mtk_gserial_ops;
gserial->gdev->type = GNSS_TYPE_MTK;
data = gnss_serial_get_drvdata(gserial);
data->vcc = devm_regulator_get(&serdev->dev, "vcc");
if (IS_ERR(data->vcc)) {
ret = PTR_ERR(data->vcc);
goto err_free_gserial;
}
data->vbackup = devm_regulator_get_optional(&serdev->dev, "vbackup");
if (IS_ERR(data->vbackup)) {
ret = PTR_ERR(data->vbackup);
if (ret == -ENODEV)
data->vbackup = NULL;
else
goto err_free_gserial;
}
if (data->vbackup) {
ret = regulator_enable(data->vbackup);
if (ret)
goto err_free_gserial;
}
ret = gnss_serial_register(gserial);
if (ret)
goto err_disable_vbackup;
return 0;
err_disable_vbackup:
if (data->vbackup)
regulator_disable(data->vbackup);
err_free_gserial:
gnss_serial_free(gserial);
return ret;
}
static void mtk_remove(struct serdev_device *serdev)
{
struct gnss_serial *gserial = serdev_device_get_drvdata(serdev);
struct mtk_data *data = gnss_serial_get_drvdata(gserial);
gnss_serial_deregister(gserial);
if (data->vbackup)
regulator_disable(data->vbackup);
gnss_serial_free(gserial);
};
#ifdef CONFIG_OF
static const struct of_device_id mtk_of_match[] = {
{ .compatible = "globaltop,pa6h" },
{},
};
MODULE_DEVICE_TABLE(of, mtk_of_match);
#endif
static struct serdev_device_driver mtk_driver = {
.driver = {
.name = "gnss-mtk",
.of_match_table = of_match_ptr(mtk_of_match),
.pm = &gnss_serial_pm_ops,
},
.probe = mtk_probe,
.remove = mtk_remove,
};
module_serdev_device_driver(mtk_driver);
MODULE_AUTHOR("Loys Ollivier <lollivier@baylibre.com>");
MODULE_DESCRIPTION("Mediatek GNSS receiver driver");
MODULE_LICENSE("GPL v2");
This diff is collapsed.
......@@ -984,7 +984,9 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv)
{
int ret;
ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops);
ret = component_add_typed(dev_priv->drm.dev,
&i915_audio_component_bind_ops,
I915_COMPONENT_AUDIO);
if (ret < 0) {
DRM_ERROR("failed to add audio component (%d)\n", ret);
/* continue with reduced functionality */
......
......@@ -26,6 +26,7 @@
#define _INTEL_DISPLAY_H_
#include <drm/drm_util.h>
#include <drm/i915_drm.h>
enum i915_gpio {
GPIOA,
......@@ -150,21 +151,6 @@ enum plane_id {
for ((__p) = PLANE_PRIMARY; (__p) < I915_MAX_PLANES; (__p)++) \
for_each_if((__crtc)->plane_ids_mask & BIT(__p))
enum port {
PORT_NONE = -1,
PORT_A = 0,
PORT_B,
PORT_C,
PORT_D,
PORT_E,
PORT_F,
I915_MAX_PORTS
};
#define port_name(p) ((p) + 'A')
/*
* Ports identifier referenced from other drivers.
* Expected to remain stable over time
......
......@@ -5,6 +5,7 @@ config DRM_MSM
depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
depends on OF && COMMON_CLK
depends on MMU
depends on INTERCONNECT || !INTERCONNECT
select QCOM_MDT_LOADER if ARCH_QCOM
select REGULATOR
select DRM_KMS_HELPER
......
This diff is collapsed.
This diff is collapsed.
......@@ -19,6 +19,7 @@
#define __MSM_GPU_H__
#include <linux/clk.h>
#include <linux/interconnect.h>
#include <linux/regulator/consumer.h>
#include "msm_drv.h"
......@@ -118,6 +119,8 @@ struct msm_gpu {
struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
uint32_t fast_rate;
struct icc_path *icc_path;
/* Hang and Inactivity Detection:
*/
#define DRM_MSM_INACTIVE_PERIOD 66 /* in ms (roughly four frames) */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment