13 Commits

Author SHA1 Message Date
Han Gao
ec72e51306 fix: gpu_bxm_4_64-kernel: enable dvfs
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-07 00:55:58 +08:00
Han Gao
aca5943dcc sync: gpu_bxm_4_64-kernel: Linux_SDK_V1.4.2
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 22:53:16 +08:00
Han Gao
42c464e64e sync: vpu-vc8000e-kernel: Linux_SDK_V1.4.2
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:09 +08:00
Han Gao
b289e7c526 sync: vpu-vc8000e-kernel: Linux_SDK_V1.3.3
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:09 +08:00
Han Gao
0d7d81fcb2 sync: vpu-vc8000e-kernel: Linux_SDK_V1.2.1
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:09 +08:00
Han Gao
71dc346184 revert: vc8000e: support mmap in fops
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:09 +08:00
Han Gao
d6bc7eb396 sync: vpu-vc8000d-kernel: Linux_SDK_V1.4.2
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:09 +08:00
Han Gao
90820cc82a sync: vpu-vc8000d-kernel: Linux_SDK_V1.3.3
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:11:06 +08:00
Han Gao
d8bd0e5590 sync: vpu-vc8000d-kernel: Linux_SDK_V1.2.1
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 19:10:08 +08:00
Han Gao
350bdb61e1 fix: nna: use VHA_THEAD_LIGHT instead of THEAD_LIGHT_FPGA_C910
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 14:59:31 +08:00
Han Gao
e32000fbc0 sync: configs: enable PM_DEVFREQ
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 14:41:24 +08:00
Han Gao
88bd214b7e sync: npu: ax3386 sdk 1.4.2
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 14:40:28 +08:00
Han Gao
bc48e4fc49 sync: npu: ax3386 sdk 1.3.3
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
2024-03-06 14:37:05 +08:00
39 changed files with 3387 additions and 5388 deletions

View File

@@ -8,16 +8,16 @@ on:
- cron: "0 2 * * *"
env:
xuantie_toolchain: https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1705395627867
toolchain_file_name: Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.8.1-20240115.tar.gz
mainline_toolchain: https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.03.01
mainline_toolchain_file_name: riscv64-glibc-ubuntu-22.04-gcc-nightly-2024.03.01-nightly.tar.gz
xuantie_toolchain: https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1698113812618
toolchain_file_name: Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.8.0-20231018.tar.gz
mainline_toolchain: https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.10.18
mainline_toolchain_file_name: riscv64-glibc-ubuntu-22.04-gcc-nightly-2023.10.18-nightly.tar.gz
wget_alias: 'wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 0'
ARCH: riscv
board: th1520
board: lpi4a
KBUILD_BUILD_USER: builder
KBUILD_BUILD_HOST: revyos-riscv-builder
KDEB_COMPRESS: none
KDEB_COMPRESS: xz
KDEB_CHANGELOG_DIST: unstable
jobs:
@@ -25,27 +25,22 @@ jobs:
strategy:
fail-fast: false
matrix:
include:
- name: gcc-13
cross: riscv64-unknown-linux-gnu-
machine: ubuntu-22.04
run_image: ghcr.io/revyos/revyos-kernel-builder:amd64-2024.04.02
- name: thead-gcc
cross: riscv64-unknown-linux-gnu-
machine: ubuntu-22.04
run_image: ghcr.io/revyos/revyos-kernel-builder:amd64-2024.04.02
- name: native
cross: riscv64-linux-gnu-
machine: [ self-hosted, Linux, riscv64 ]
run_image: ghcr.io/revyos/revyos-kernel-builder:riscv64-2024.04.02
name: [thead-gcc, gcc-13]
board: [lpi4a, ahead]
runs-on: ${{ matrix.machine }}
container:
image: ${{ matrix.run_image }}
runs-on: ubuntu-22.04
env:
CROSS_COMPILE: ${{ matrix.cross }}
CROSS_COMPILE: riscv64-unknown-linux-gnu-
steps:
- name: Install software
run: |
sudo apt update && \
sudo apt install -y gdisk dosfstools g++-12-riscv64-linux-gnu build-essential \
libncurses-dev gawk flex bison openssl libssl-dev tree \
dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf device-tree-compiler \
devscripts pahole
- name: Checkout kernel
uses: actions/checkout@v4
with:
@@ -57,40 +52,37 @@ jobs:
if [[ ${{ matrix.name }} = "thead-gcc" ]]; then
${wget_alias} ${xuantie_toolchain}/${toolchain_file_name}
tar -xvf ${toolchain_file_name} -C /opt
export PATH="/opt/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.8.1/bin:$PATH"
elif [[ ${{ matrix.name }} = "gcc-13" ]]; then
export PATH="/opt/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.8.0/bin:$PATH"
else
${wget_alias} ${mainline_toolchain}/${mainline_toolchain_file_name}
tar -xvf ${mainline_toolchain_file_name} -C /opt
export PATH="/opt/riscv/bin:$PATH"
else
echo "No download toolchain."
fi
${CROSS_COMPILE}gcc -v
pushd kernel
make revyos_defconfig
export KDEB_PKGVERSION="$(make kernelversion)-$(date "+%Y.%m.%d.%H.%M")+$(git rev-parse --short HEAD)"
if [ x"${{ matrix.board }}" = x"lpi4a" ]; then
make revyos_defconfig
elif [ x"${{ matrix.board }}" = x"ahead" ]; then
make revyos_beaglev_defconfig
fi
export KDEB_PKGVERSION="$(date "+%Y.%m.%d.%H.%M")+$(git rev-parse --short HEAD)"
sed -i '/CONFIG_LOCALVERSION_AUTO/d' .config && echo "CONFIG_LOCALVERSION_AUTO=n" >> .config
cat .config | grep "CONFIG_THEAD_ISA"
if [ `uname -m` = "riscv64" ]; then
# FIXME: force use 32 thread
make -j32 bindeb-pkg LOCALVERSION="-${board}"
else
make -j$(nproc) bindeb-pkg LOCALVERSION="-${board}"
fi
make -j$(nproc) bindeb-pkg LOCALVERSION="-${{ matrix.board }}"
# Copy deb
dcmd cp -v ../*.changes ${GITHUB_WORKSPACE}/rootfs/
sudo dcmd cp -v ../*.changes ${GITHUB_WORKSPACE}/rootfs/
# record commit-id
git rev-parse HEAD > kernel-commitid
cp -v kernel-commitid ${GITHUB_WORKSPACE}/rootfs/
git rev-parse HEAD > ${{ matrix.board }}-kernel-commitid
sudo cp -v ${{ matrix.board }}-kernel-commitid ${GITHUB_WORKSPACE}/rootfs/
ls -al ${GITHUB_WORKSPACE}/rootfs/
popd
- name: 'Upload Artifact'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: thead-kernel-${{ matrix.name }}
path: rootfs/*

View File

@@ -5,8 +5,7 @@ dtbo-$(CONFIG_SOC_THEAD) += \
BBORG_RELAY-00A2.dtbo \
BONE-LED_P8_03.dtbo \
BONE-LED_P9_11.dtbo \
BVA-MIKROBUS-0.dtbo \
meles-wifibt-external-antenna.dtbo
BVA-MIKROBUS-0.dtbo
targets += dtbs dtbs_install
targets += $(dtbo-y)

View File

@@ -1,28 +0,0 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target-path = "/";
__overlay__ {
ext_antenna: ext-antenna {
status = "okay";
compatible = "regulator-fixed";
enable-active-low;
gpio = <&gpio1_porta 24 1>;
regulator-always-on;
regulator-boot-on;
regulator-name = "ext_antenna";
};
};
};
fragment@1 {
target = <&board_antenna>;
__overlay__ {
status = "disabled";
};
};
};

View File

@@ -8,7 +8,6 @@
/ {
model = "T-HEAD Light Lichee Pi 4A configuration for LicheeConsole4A";
compatible = "thead,light", "sipeed,th1520-laptop", "sipeed,console4a";
};
&dsi0_panel0 {

View File

@@ -7,7 +7,6 @@
/ {
model = "T-HEAD Light Lichee Pi 4A configuration for 8GB DDR board use on laptop";
compatible = "thead,light", "sipeed,th1520-laptop";
reg_sys_vcc_5v: regulator-sys-vcc-5v-en {
status = "okay";
@@ -20,15 +19,12 @@
regulator-boot-on;
regulator-always-on;
// suspend for lichee laptop is not ready so dont turn it off
/*
regulator-state-mem {
regulator-off-in-suspend;
};
regulator-state-standby {
regulator-off-in-suspend;
};
*/
};
reg_sys_vcc_3v3: regulator-sys-vcc-3v3-en {
@@ -119,7 +115,7 @@
charger: dc-charger {
compatible = "gpio-charger";
charger-type = "mains";
gpios = <&gpio0_porta 16 GPIO_ACTIVE_HIGH>;
gpios = <&ao_gpio_porta 2 GPIO_ACTIVE_HIGH>;
};
};
@@ -232,7 +228,6 @@
&uart3 {
clock-frequency = <100000000>;
pinctrl-0 = <&pinctrl_uart3_tx_is_gpio>;
status = "okay";
};

View File

@@ -296,10 +296,10 @@
debounce-interval = <1>;
gpios = <&gpio2_porta 25 0x1>;
};
key-wake {
label = "Wake Key";
key-sleep {
label = "Sleep Wake Key";
wakeup-source;
linux,code = <KEY_WAKEUP>;
linux,code = <KEY_SLEEP>;
debounce-interval = <1>;
gpios = <&ao_gpio_porta 2 0x1>;
};
@@ -1105,16 +1105,6 @@
>;
};
pinctrl_uart3_tx_is_gpio: uart3txisgpiogrp {
thead,pins = <
FM_UART3_TXD 0x3 0x202
FM_UART3_RXD 0x1 0x202
>;
};
pinctrl_wifi_wake: wifi_grp {
thead,pins = <
FM_GPIO0_27 0x0 0x202

View File

@@ -265,36 +265,15 @@
status = "okay";
};
usb_vbus_en: regulator-usb-vbus-en {
vcc_usb_en: regulator-usb-en {
compatible = "regulator-fixed";
regulator-name = "usb_vbus_en";
gpio = <&gpio0_porta 27 0>; /* GPIO_ACTIVE_HIGH: 0 */
enable-active-high;
regulator-boot-on;
regulator-always-on;
status = "okay";
};
/* Select USB3.0 Type-A port */
usb_select: regulator-usb-select {
compatible = "regulator-fixed";
regulator-name = "usb_select";
regulator-name = "vcc_usb_en";
gpio = <&gpio2_porta 30 1>; /* GPIO_ACTIVE_LOW: 1 */
regulator-boot-on;
regulator-always-on;
status = "okay";
};
board_antenna: board-antenna {
status = "okay";
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio1_porta 24 0>;
regulator-always-on;
regulator-boot-on;
regulator-name = "board_antenna";
};
aon {
compatible = "thead,light-aon";
mbox-names = "aon";

View File

@@ -1319,6 +1319,7 @@ CONFIG_BT_DEBUGFS=y
# CONFIG_BT_HCIBTSDIO is not set
CONFIG_BT_HCIUART=y
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_RTL3WIRE=y
# CONFIG_BT_HCIUART_BCSP is not set
# CONFIG_BT_HCIUART_ATH3K is not set
# CONFIG_BT_HCIUART_INTEL is not set

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -115,6 +115,14 @@ config BT_HCIUART_H4
Say Y here to compile support for HCI UART (H4) protocol.
config BT_HCIUART_RTL3WIRE
bool "Realtek Three-wire UART (H5) protocol support"
depends on BT_HCIUART
help
Realtek Three-wire UART (H5) transport layer makes it possible
to use Realtek Bluetooth controller with Three-wire UART.
Say Y here to compile support for Realtek Three-wire UART.
config BT_HCIUART_NOKIA
tristate "UART Nokia H4+ protocol support"
depends on BT_HCIUART
@@ -425,6 +433,4 @@ config BT_HCIRSI
Say Y here to compile support for HCI over Redpine into the
kernel or say M to compile as a module.
source "drivers/bluetooth/rtkbt/Kconfig"
endmenu

View File

@@ -45,6 +45,6 @@ hci_uart-$(CONFIG_BT_HCIUART_BCM) += hci_bcm.o
hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o
hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
hci_uart-y += rtk_coex.o
hci_uart-$(CONFIG_BT_HCIUART_RTL3WIRE) += hci_rtk_h5.o
hci_uart-objs := $(hci_uart-y)
obj-$(CONFIG_BT_RTKBT) += rtkbt/

View File

@@ -654,6 +654,7 @@ static const struct h4_recv_pkt bcm_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ H4_RECV_ISO, .recv = hci_recv_frame },
{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag },
{ BCM_RECV_NULL, .recv = hci_recv_diag },
{ BCM_RECV_TYPE49, .recv = hci_recv_diag },

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* Bluetooth HCI UART driver
@@ -6,10 +5,25 @@
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -17,7 +31,6 @@
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/errno.h>
@@ -25,18 +38,32 @@
#include <linux/signal.h>
#include <linux/ioctl.h>
#include <linux/skbuff.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <linux/version.h>
#include "hci_uart.h"
#ifdef BTCOEX
#include "rtk_coex.h"
#endif
//#define VERSION "1.2"
struct h4_struct {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
};
/* H4 receiver States */
#define H4_W4_PACKET_TYPE 0
#define H4_W4_EVENT_HDR 1
#define H4_W4_ACL_HDR 2
#define H4_W4_SCO_HDR 3
#define H4_W4_DATA 4
/* Initialize protocol */
static int h4_open(struct hci_uart *hu)
{
@@ -44,7 +71,7 @@ static int h4_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
h4 = kzalloc(sizeof(*h4), GFP_KERNEL);
h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
if (!h4)
return -ENOMEM;
@@ -71,6 +98,8 @@ static int h4_close(struct hci_uart *hu)
{
struct h4_struct *h4 = hu->priv;
hu->priv = NULL;
BT_DBG("hu %p", hu);
skb_queue_purge(&h4->txq);
@@ -83,7 +112,7 @@ static int h4_close(struct hci_uart *hu)
return 0;
}
/* Enqueue frame for transmission (padding, crc, etc) */
/* Enqueue frame for transmittion (padding, crc, etc) */
static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
struct h4_struct *h4 = hu->priv;
@@ -91,34 +120,174 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
BT_DBG("hu %p skb %p", hu, skb);
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&h4->txq, skb);
return 0;
}
static const struct h4_recv_pkt h4_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ H4_RECV_ISO, .recv = hci_recv_frame },
};
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
static inline int h4_check_data_len(struct h4_struct *h4, int len)
#else
static inline int h4_check_data_len(struct hci_dev *hdev, struct h4_struct *h4, int len)
#endif
{
register int room = skb_tailroom(h4->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
hci_recv_frame(h4->rx_skb);
#else
hci_recv_frame(hdev, h4->rx_skb);
#endif
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(h4->rx_skb);
} else {
h4->rx_state = H4_W4_DATA;
h4->rx_count = len;
return len;
}
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
return 0;
}
/* Recv data */
static int h4_recv(struct hci_uart *hu, const void *data, int count)
static int h4_recv(struct hci_uart *hu, void *data, int count)
{
struct h4_struct *h4 = hu->priv;
register char *ptr;
struct hci_event_hdr *eh;
struct hci_acl_hdr *ah;
struct hci_sco_hdr *sh;
register int len, type, dlen;
if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
return -EUNATCH;
BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
hu, count, h4->rx_state, h4->rx_count);
h4->rx_skb = h4_recv_buf(hu->hdev, h4->rx_skb, data, count,
h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));
if (IS_ERR(h4->rx_skb)) {
int err = PTR_ERR(h4->rx_skb);
bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
h4->rx_skb = NULL;
return err;
ptr = data;
while (count) {
if (h4->rx_count) {
len = min_t(unsigned int, h4->rx_count, count);
memcpy(skb_put(h4->rx_skb, len), ptr, len);
h4->rx_count -= len; count -= len; ptr += len;
if (h4->rx_count)
continue;
switch (h4->rx_state) {
case H4_W4_DATA:
BT_DBG("Complete data");
#ifdef BTCOEX
if(bt_cb(h4->rx_skb)->pkt_type == HCI_EVENT_PKT)
rtk_btcoex_parse_event(
h4->rx_skb->data,
h4->rx_skb->len);
if(bt_cb(h4->rx_skb)->pkt_type == HCI_ACLDATA_PKT)
rtk_btcoex_parse_l2cap_data_rx(
h4->rx_skb->data,
h4->rx_skb->len);
#endif
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
hci_recv_frame(h4->rx_skb);
#else
hci_recv_frame(hu->hdev, h4->rx_skb);
#endif
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
continue;
case H4_W4_EVENT_HDR:
eh = hci_event_hdr(h4->rx_skb);
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, eh->plen);
#else
h4_check_data_len(hu->hdev, h4, eh->plen);
#endif
continue;
case H4_W4_ACL_HDR:
ah = hci_acl_hdr(h4->rx_skb);
dlen = __le16_to_cpu(ah->dlen);
BT_DBG("ACL header: dlen %d", dlen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, dlen);
#else
h4_check_data_len(hu->hdev, h4, dlen);
#endif
continue;
case H4_W4_SCO_HDR:
sh = hci_sco_hdr(h4->rx_skb);
BT_DBG("SCO header: dlen %d", sh->dlen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, sh->dlen);
#else
h4_check_data_len(hu->hdev, h4, sh->dlen);
#endif
continue;
}
}
/* H4_W4_PACKET_TYPE */
switch (*ptr) {
case HCI_EVENT_PKT:
BT_DBG("Event packet");
h4->rx_state = H4_W4_EVENT_HDR;
h4->rx_count = HCI_EVENT_HDR_SIZE;
type = HCI_EVENT_PKT;
break;
case HCI_ACLDATA_PKT:
BT_DBG("ACL packet");
h4->rx_state = H4_W4_ACL_HDR;
h4->rx_count = HCI_ACL_HDR_SIZE;
type = HCI_ACLDATA_PKT;
break;
case HCI_SCODATA_PKT:
BT_DBG("SCO packet");
h4->rx_state = H4_W4_SCO_HDR;
h4->rx_count = HCI_SCO_HDR_SIZE;
type = HCI_SCODATA_PKT;
break;
default:
BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
hu->hdev->stat.err_rx++;
ptr++; count--;
continue;
};
ptr++; count--;
/* Allocate packet */
h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!h4->rx_skb) {
BT_ERR("Can't allocate mem for new packet");
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_count = 0;
return -ENOMEM;
}
h4->rx_skb->dev = (void *) hu->hdev;
bt_cb(h4->rx_skb)->pkt_type = type;
}
return count;
@@ -130,9 +299,8 @@ static struct sk_buff *h4_dequeue(struct hci_uart *hu)
return skb_dequeue(&h4->txq);
}
static const struct hci_uart_proto h4p = {
static struct hci_uart_proto h4p = {
.id = HCI_UART_H4,
.name = "H4",
.open = h4_open,
.close = h4_close,
.recv = h4_recv,
@@ -143,132 +311,17 @@ static const struct hci_uart_proto h4p = {
int __init h4_init(void)
{
return hci_uart_register_proto(&h4p);
int err = hci_uart_register_proto(&h4p);
if (!err)
BT_INFO("HCI H4 protocol initialized");
else
BT_ERR("HCI H4 protocol registration failed");
return err;
}
int __exit h4_deinit(void)
{
return hci_uart_unregister_proto(&h4p);
}
struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
const unsigned char *buffer, int count,
const struct h4_recv_pkt *pkts, int pkts_count)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
u8 alignment = hu->alignment ? hu->alignment : 1;
/* Check for error from previous call */
if (IS_ERR(skb))
skb = NULL;
while (count) {
int i, len;
/* remove padding bytes from buffer */
for (; hu->padding && count > 0; hu->padding--) {
count--;
buffer++;
}
if (!count)
break;
if (!skb) {
for (i = 0; i < pkts_count; i++) {
if (buffer[0] != (&pkts[i])->type)
continue;
skb = bt_skb_alloc((&pkts[i])->maxlen,
GFP_ATOMIC);
if (!skb)
return ERR_PTR(-ENOMEM);
hci_skb_pkt_type(skb) = (&pkts[i])->type;
hci_skb_expect(skb) = (&pkts[i])->hlen;
break;
}
/* Check for invalid packet type */
if (!skb)
return ERR_PTR(-EILSEQ);
count -= 1;
buffer += 1;
}
len = min_t(uint, hci_skb_expect(skb) - skb->len, count);
skb_put_data(skb, buffer, len);
count -= len;
buffer += len;
/* Check for partial packet */
if (skb->len < hci_skb_expect(skb))
continue;
for (i = 0; i < pkts_count; i++) {
if (hci_skb_pkt_type(skb) == (&pkts[i])->type)
break;
}
if (i >= pkts_count) {
kfree_skb(skb);
return ERR_PTR(-EILSEQ);
}
if (skb->len == (&pkts[i])->hlen) {
u16 dlen;
switch ((&pkts[i])->lsize) {
case 0:
/* No variable data length */
dlen = 0;
break;
case 1:
/* Single octet variable length */
dlen = skb->data[(&pkts[i])->loff];
hci_skb_expect(skb) += dlen;
if (skb_tailroom(skb) < dlen) {
kfree_skb(skb);
return ERR_PTR(-EMSGSIZE);
}
break;
case 2:
/* Double octet variable length */
dlen = get_unaligned_le16(skb->data +
(&pkts[i])->loff);
hci_skb_expect(skb) += dlen;
if (skb_tailroom(skb) < dlen) {
kfree_skb(skb);
return ERR_PTR(-EMSGSIZE);
}
break;
default:
/* Unsupported variable length */
kfree_skb(skb);
return ERR_PTR(-EILSEQ);
}
if (!dlen) {
hu->padding = (skb->len - 1) % alignment;
hu->padding = (alignment - hu->padding) % alignment;
/* No more data, complete frame */
(&pkts[i])->recv(hdev, skb);
skb = NULL;
}
} else {
hu->padding = (skb->len - 1) % alignment;
hu->padding = (alignment - hu->padding) % alignment;
/* Complete frame */
(&pkts[i])->recv(hdev, skb);
skb = NULL;
}
}
return skb;
}
EXPORT_SYMBOL_GPL(h4_recv_buf);

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
*
* Bluetooth HCI UART driver
@@ -6,12 +5,50 @@
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/version.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
#define HCI_VERSION_CODE LINUX_VERSION_CODE
#ifndef N_HCI
#define N_HCI 15
#endif
#ifndef CONFIG_BT_HCIUART_H4
#define CONFIG_BT_HCIUART_H4
#endif
#define BTCOEX
/* Send host sleep notification to Controller */
#define WOBT_NOTIFY 0 /* 1 enable; 0 disable */
/* Send LE whitelist only for Background scan parameters */
#define WOBT_NOTIFY_BG_SCAN_LE_WHITELIST_ONLY (0 * WOBT_NOTIFY) /* 1 enable; 0 disable */
/* RTKBT Power-on Whitelist for sideband wake-up by LE Advertising from Remote.
* Note that it's necessary to apply TV FW Patch. */
#define RTKBT_TV_POWERON_WHITELIST (0 * WOBT_NOTIFY) /* 1 enable; 0 disable */
/* Ioctls */
#define HCIUARTSETPROTO _IOW('U', 200, int)
#define HCIUARTGETPROTO _IOR('U', 201, int)
@@ -20,7 +57,7 @@
#define HCIUARTGETFLAGS _IOR('U', 204, int)
/* UART protocols */
#define HCI_UART_MAX_PROTO 12
#define HCI_UART_MAX_PROTO 6
#define HCI_UART_H4 0
#define HCI_UART_BCSP 1
@@ -28,12 +65,6 @@
#define HCI_UART_H4DS 3
#define HCI_UART_LL 4
#define HCI_UART_ATH3K 5
#define HCI_UART_INTEL 6
#define HCI_UART_BCM 7
#define HCI_UART_QCA 8
#define HCI_UART_AG6XX 9
#define HCI_UART_NOKIA 10
#define HCI_UART_MRVL 11
#define HCI_UART_RAW_DEVICE 0
#define HCI_UART_RESET_ON_INIT 1
@@ -43,46 +74,42 @@
#define HCI_UART_VND_DETECT 5
struct hci_uart;
struct serdev_device;
struct hci_uart_proto {
unsigned int id;
const char *name;
unsigned int manufacturer;
unsigned int init_speed;
unsigned int oper_speed;
int (*open)(struct hci_uart *hu);
int (*close)(struct hci_uart *hu);
int (*flush)(struct hci_uart *hu);
int (*setup)(struct hci_uart *hu);
int (*set_baudrate)(struct hci_uart *hu, unsigned int speed);
int (*recv)(struct hci_uart *hu, const void *data, int len);
int (*recv)(struct hci_uart *hu, void *data, int len);
int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
struct sk_buff *(*dequeue)(struct hci_uart *hu);
};
struct hci_uart {
struct tty_struct *tty;
struct serdev_device *serdev;
struct hci_dev *hdev;
unsigned long flags;
unsigned long hdev_flags;
struct work_struct init_ready;
struct work_struct write_work;
struct workqueue_struct *hci_uart_wq;
const struct hci_uart_proto *proto;
struct percpu_rw_semaphore proto_lock; /* Stop work for proto close */
struct hci_uart_proto *proto;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
struct percpu_rw_semaphore proto_lock; /* Stop work for proto close */
#else
struct rw_semaphore proto_lock;
#endif
void *priv;
struct semaphore tx_sem; /* semaphore for tx */
struct sk_buff *tx_skb;
unsigned long tx_state;
unsigned int init_speed;
unsigned int oper_speed;
u8 alignment;
u8 padding;
#if WOBT_NOTIFY
struct notifier_block pm_notify_block;
#endif
};
/* HCI_UART proto flag bits */
@@ -94,108 +121,20 @@ struct hci_uart {
#define HCI_UART_SENDING 1
#define HCI_UART_TX_WAKEUP 2
int hci_uart_register_proto(const struct hci_uart_proto *p);
int hci_uart_unregister_proto(const struct hci_uart_proto *p);
int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p);
void hci_uart_unregister_device(struct hci_uart *hu);
int hci_uart_tx_wakeup(struct hci_uart *hu);
int hci_uart_wait_until_sent(struct hci_uart *hu);
int hci_uart_init_ready(struct hci_uart *hu);
void hci_uart_init_work(struct work_struct *work);
void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
bool hci_uart_has_flow_control(struct hci_uart *hu);
void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
unsigned int oper_speed);
extern int hci_uart_register_proto(struct hci_uart_proto *p);
extern int hci_uart_unregister_proto(struct hci_uart_proto *p);
extern int hci_uart_tx_wakeup(struct hci_uart *hu);
#ifdef CONFIG_BT_HCIUART_H4
int h4_init(void);
int h4_deinit(void);
struct h4_recv_pkt {
u8 type; /* Packet type */
u8 hlen; /* Header length */
u8 loff; /* Data length offset in header */
u8 lsize; /* Data length field size */
u16 maxlen; /* Max overall packet length */
int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
};
#define H4_RECV_ACL \
.type = HCI_ACLDATA_PKT, \
.hlen = HCI_ACL_HDR_SIZE, \
.loff = 2, \
.lsize = 2, \
.maxlen = HCI_MAX_FRAME_SIZE \
#define H4_RECV_SCO \
.type = HCI_SCODATA_PKT, \
.hlen = HCI_SCO_HDR_SIZE, \
.loff = 2, \
.lsize = 1, \
.maxlen = HCI_MAX_SCO_SIZE
#define H4_RECV_EVENT \
.type = HCI_EVENT_PKT, \
.hlen = HCI_EVENT_HDR_SIZE, \
.loff = 1, \
.lsize = 1, \
.maxlen = HCI_MAX_EVENT_SIZE
#define H4_RECV_ISO \
.type = HCI_ISODATA_PKT, \
.hlen = HCI_ISO_HDR_SIZE, \
.loff = 2, \
.lsize = 2, \
.maxlen = HCI_MAX_FRAME_SIZE \
struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
const unsigned char *buffer, int count,
const struct h4_recv_pkt *pkts, int pkts_count);
extern int h4_init(void);
extern int h4_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_BCSP
int bcsp_init(void);
int bcsp_deinit(void);
#endif
extern int h5_init(void);
extern int h5_deinit(void);
#ifdef CONFIG_BT_HCIUART_LL
int ll_init(void);
int ll_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_ATH3K
int ath_init(void);
int ath_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_3WIRE
int h5_init(void);
int h5_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_INTEL
int intel_init(void);
int intel_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_BCM
int bcm_init(void);
int bcm_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_QCA
int qca_init(void);
int qca_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_AG6XX
int ag6xx_init(void);
int ag6xx_deinit(void);
#endif
#ifdef CONFIG_BT_HCIUART_MRVL
int mrvl_init(void);
int mrvl_deinit(void);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
extern int hci_uart_send_frame(struct sk_buff *skb);
#else
extern int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb);
#endif

View File

@@ -1,5 +0,0 @@
config BT_RTKBT
tristate "BT_RTKBT"
default n
help
Help message of RTKBT

View File

@@ -1,2 +0,0 @@
obj-$(CONFIG_BT_RTKBT) := rtkbt.o
rtkbt-objs := hci_ldisc.o hci_h4.o hci_rtk_h5.o rtk_coex.o

View File

@@ -1,327 +0,0 @@
/*
*
* Bluetooth HCI UART driver
*
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/signal.h>
#include <linux/ioctl.h>
#include <linux/skbuff.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <linux/version.h>
#include "hci_uart.h"
#ifdef BTCOEX
#include "rtk_coex.h"
#endif
//#define VERSION "1.2"
struct h4_struct {
unsigned long rx_state;
unsigned long rx_count;
struct sk_buff *rx_skb;
struct sk_buff_head txq;
};
/* H4 receiver States */
#define H4_W4_PACKET_TYPE 0
#define H4_W4_EVENT_HDR 1
#define H4_W4_ACL_HDR 2
#define H4_W4_SCO_HDR 3
#define H4_W4_DATA 4
/* Initialize protocol */
static int h4_open(struct hci_uart *hu)
{
struct h4_struct *h4;
BT_DBG("hu %p", hu);
h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
if (!h4)
return -ENOMEM;
skb_queue_head_init(&h4->txq);
hu->priv = h4;
return 0;
}
/* Flush protocol data */
static int h4_flush(struct hci_uart *hu)
{
struct h4_struct *h4 = hu->priv;
BT_DBG("hu %p", hu);
skb_queue_purge(&h4->txq);
return 0;
}
/* Close protocol */
static int h4_close(struct hci_uart *hu)
{
struct h4_struct *h4 = hu->priv;
hu->priv = NULL;
BT_DBG("hu %p", hu);
skb_queue_purge(&h4->txq);
kfree_skb(h4->rx_skb);
hu->priv = NULL;
kfree(h4);
return 0;
}
/* Enqueue frame for transmittion (padding, crc, etc) */
static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
struct h4_struct *h4 = hu->priv;
BT_DBG("hu %p skb %p", hu, skb);
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&h4->txq, skb);
return 0;
}
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
static inline int h4_check_data_len(struct h4_struct *h4, int len)
#else
static inline int h4_check_data_len(struct hci_dev *hdev, struct h4_struct *h4, int len)
#endif
{
register int room = skb_tailroom(h4->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
hci_recv_frame(h4->rx_skb);
#else
hci_recv_frame(hdev, h4->rx_skb);
#endif
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(h4->rx_skb);
} else {
h4->rx_state = H4_W4_DATA;
h4->rx_count = len;
return len;
}
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
return 0;
}
/* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count)
{
struct h4_struct *h4 = hu->priv;
register char *ptr;
struct hci_event_hdr *eh;
struct hci_acl_hdr *ah;
struct hci_sco_hdr *sh;
register int len, type, dlen;
BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
hu, count, h4->rx_state, h4->rx_count);
ptr = data;
while (count) {
if (h4->rx_count) {
len = min_t(unsigned int, h4->rx_count, count);
memcpy(skb_put(h4->rx_skb, len), ptr, len);
h4->rx_count -= len; count -= len; ptr += len;
if (h4->rx_count)
continue;
switch (h4->rx_state) {
case H4_W4_DATA:
BT_DBG("Complete data");
#ifdef BTCOEX
if(bt_cb(h4->rx_skb)->pkt_type == HCI_EVENT_PKT)
rtk_btcoex_parse_event(
h4->rx_skb->data,
h4->rx_skb->len);
if(bt_cb(h4->rx_skb)->pkt_type == HCI_ACLDATA_PKT)
rtk_btcoex_parse_l2cap_data_rx(
h4->rx_skb->data,
h4->rx_skb->len);
#endif
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
hci_recv_frame(h4->rx_skb);
#else
hci_recv_frame(hu->hdev, h4->rx_skb);
#endif
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
continue;
case H4_W4_EVENT_HDR:
eh = hci_event_hdr(h4->rx_skb);
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, eh->plen);
#else
h4_check_data_len(hu->hdev, h4, eh->plen);
#endif
continue;
case H4_W4_ACL_HDR:
ah = hci_acl_hdr(h4->rx_skb);
dlen = __le16_to_cpu(ah->dlen);
BT_DBG("ACL header: dlen %d", dlen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, dlen);
#else
h4_check_data_len(hu->hdev, h4, dlen);
#endif
continue;
case H4_W4_SCO_HDR:
sh = hci_sco_hdr(h4->rx_skb);
BT_DBG("SCO header: dlen %d", sh->dlen);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
h4_check_data_len(h4, sh->dlen);
#else
h4_check_data_len(hu->hdev, h4, sh->dlen);
#endif
continue;
}
}
/* H4_W4_PACKET_TYPE */
switch (*ptr) {
case HCI_EVENT_PKT:
BT_DBG("Event packet");
h4->rx_state = H4_W4_EVENT_HDR;
h4->rx_count = HCI_EVENT_HDR_SIZE;
type = HCI_EVENT_PKT;
break;
case HCI_ACLDATA_PKT:
BT_DBG("ACL packet");
h4->rx_state = H4_W4_ACL_HDR;
h4->rx_count = HCI_ACL_HDR_SIZE;
type = HCI_ACLDATA_PKT;
break;
case HCI_SCODATA_PKT:
BT_DBG("SCO packet");
h4->rx_state = H4_W4_SCO_HDR;
h4->rx_count = HCI_SCO_HDR_SIZE;
type = HCI_SCODATA_PKT;
break;
default:
BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
hu->hdev->stat.err_rx++;
ptr++; count--;
continue;
};
ptr++; count--;
/* Allocate packet */
h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!h4->rx_skb) {
BT_ERR("Can't allocate mem for new packet");
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_count = 0;
return -ENOMEM;
}
h4->rx_skb->dev = (void *) hu->hdev;
bt_cb(h4->rx_skb)->pkt_type = type;
}
return count;
}
static struct sk_buff *h4_dequeue(struct hci_uart *hu)
{
struct h4_struct *h4 = hu->priv;
return skb_dequeue(&h4->txq);
}
static struct hci_uart_proto h4p = {
.id = HCI_UART_H4,
.open = h4_open,
.close = h4_close,
.recv = h4_recv,
.enqueue = h4_enqueue,
.dequeue = h4_dequeue,
.flush = h4_flush,
};
int __init h4_init(void)
{
int err = hci_uart_register_proto(&h4p);
if (!err)
BT_INFO("HCI H4 protocol initialized");
else
BT_ERR("HCI H4 protocol registration failed");
return err;
}
int __exit h4_deinit(void)
{
return hci_uart_unregister_proto(&h4p);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,145 +0,0 @@
/*
*
* Bluetooth HCI UART driver
*
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/version.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
#define HCI_VERSION_CODE LINUX_VERSION_CODE
#ifndef N_HCI
#define N_HCI 15
#endif
#ifndef CONFIG_BT_HCIUART_H4
#define CONFIG_BT_HCIUART_H4
#endif
#define BTCOEX
/* Send host sleep notification to Controller */
#define WOBT_NOTIFY 0 /* 1 enable; 0 disable */
/* Send LE whitelist only for Background scan parameters */
#define WOBT_NOTIFY_BG_SCAN_LE_WHITELIST_ONLY (0 * WOBT_NOTIFY) /* 1 enable; 0 disable */
/* RTKBT Power-on Whitelist for sideband wake-up by LE Advertising from Remote.
* Note that it's necessary to apply TV FW Patch. */
#define RTKBT_TV_POWERON_WHITELIST (0 * WOBT_NOTIFY) /* 1 enable; 0 disable */
/* RTKBT Power-on Data Filter for Manufacturer field */
/* Note that please edit the datafilter in
* rtkbt_set_le_device_poweron_data_filter() of hci_ldisc.c */
#define RTKBT_TV_POWERON_DATA_FILTER (0 * WOBT_NOTIFY) /* 1 enable; 0 disable */
/* Ioctls */
#define HCIUARTSETPROTO _IOW('U', 200, int)
#define HCIUARTGETPROTO _IOR('U', 201, int)
#define HCIUARTGETDEVICE _IOR('U', 202, int)
#define HCIUARTSETFLAGS _IOW('U', 203, int)
#define HCIUARTGETFLAGS _IOR('U', 204, int)
/* UART protocols */
#define HCI_UART_MAX_PROTO 6
#define HCI_UART_H4 0
#define HCI_UART_BCSP 1
#define HCI_UART_3WIRE 2
#define HCI_UART_H4DS 3
#define HCI_UART_LL 4
#define HCI_UART_ATH3K 5
#define HCI_UART_RAW_DEVICE 0
#define HCI_UART_RESET_ON_INIT 1
#define HCI_UART_CREATE_AMP 2
#define HCI_UART_INIT_PENDING 3
#define HCI_UART_EXT_CONFIG 4
#define HCI_UART_VND_DETECT 5
struct hci_uart;
struct hci_uart_proto {
unsigned int id;
int (*open)(struct hci_uart *hu);
int (*close)(struct hci_uart *hu);
int (*flush)(struct hci_uart *hu);
int (*recv)(struct hci_uart *hu, void *data, int len);
int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
struct sk_buff *(*dequeue)(struct hci_uart *hu);
};
struct hci_uart {
struct tty_struct *tty;
struct hci_dev *hdev;
unsigned long flags;
unsigned long hdev_flags;
struct work_struct write_work;
struct workqueue_struct *hci_uart_wq;
struct hci_uart_proto *proto;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
struct percpu_rw_semaphore proto_lock; /* Stop work for proto close */
#else
struct rw_semaphore proto_lock;
#endif
void *priv;
struct semaphore tx_sem; /* semaphore for tx */
struct sk_buff *tx_skb;
unsigned long tx_state;
#if WOBT_NOTIFY
struct notifier_block pm_notify_block;
#endif
};
/* HCI_UART proto flag bits */
#define HCI_UART_PROTO_SET 0
#define HCI_UART_REGISTERED 1
#define HCI_UART_PROTO_READY 2
/* TX states */
#define HCI_UART_SENDING 1
#define HCI_UART_TX_WAKEUP 2
extern int hci_uart_register_proto(struct hci_uart_proto *p);
extern int hci_uart_unregister_proto(struct hci_uart_proto *p);
extern int hci_uart_tx_wakeup(struct hci_uart *hu);
#ifdef CONFIG_BT_HCIUART_H4
extern int h4_init(void);
extern int h4_deinit(void);
#endif
extern int h5_init(void);
extern int h5_deinit(void);
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
extern int hci_uart_send_frame(struct sk_buff *skb);
#else
extern int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb);
#endif

View File

@@ -148,6 +148,7 @@
#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TDM 17
#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_RDM 15
#define SUPPORT_BUFFER_SYNC 1
#define SUPPORT_LINUX_DVFS 1
#ifdef CONFIG_DRM_POWERVR_ROGUE_DEBUG
#define DEBUG
#define DEBUG_BRIDGE_KM

View File

@@ -43,6 +43,7 @@ override SUPPORT_DI_BRG_IMPL := 1
override SUPPORT_NATIVE_FENCE_SYNC := 1
override SUPPORT_DMA_FENCE := 1
override SUPPORT_BUFFER_SYNC := 1
override SUPPORT_LINUX_DVFS := 1
ifeq ($(CONFIG_DRM_POWERVR_ROGUE_DEBUG),y)
override BUILD := debug
override PVRSRV_ENABLE_GPU_MEMORY_INFO := 1

View File

@@ -0,0 +1,138 @@
/*************************************************************************/ /*!
@File pvr_dvfs.h
@Title System level interface for DVFS
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License Dual MIT/GPLv2
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.
This License is also included in this distribution in the file called
"MIT-COPYING".
EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/
#ifndef PVR_DVFS_H
#define PVR_DVFS_H
#include <linux/version.h>
#if defined(SUPPORT_LINUX_DVFS)
#include <linux/devfreq.h>
#include <linux/thermal.h>
#if defined(CONFIG_DEVFREQ_THERMAL)
#include <linux/devfreq_cooling.h>
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
#include <linux/opp.h>
#else
#include <linux/pm_opp.h>
#endif
#endif
#include "img_types.h"
typedef void (*PFN_SYS_DEV_DVFS_SET_FREQUENCY)(IMG_UINT32 ui32Freq);
typedef void (*PFN_SYS_DEV_DVFS_SET_VOLTAGE)(IMG_UINT32 ui32Volt);
typedef struct _IMG_OPP_
{
IMG_UINT32 ui32Volt;
/*
* Unit of frequency in Hz.
*/
IMG_UINT32 ui32Freq;
} IMG_OPP;
typedef struct _IMG_DVFS_DEVICE_CFG_
{
const IMG_OPP *pasOPPTable;
IMG_UINT32 ui32OPPTableSize;
#if defined(SUPPORT_LINUX_DVFS)
IMG_UINT32 ui32PollMs;
#endif
IMG_BOOL bIdleReq;
PFN_SYS_DEV_DVFS_SET_FREQUENCY pfnSetFrequency;
PFN_SYS_DEV_DVFS_SET_VOLTAGE pfnSetVoltage;
#if defined(CONFIG_DEVFREQ_THERMAL) && defined(SUPPORT_LINUX_DVFS)
struct devfreq_cooling_power *psPowerOps;
#endif
} IMG_DVFS_DEVICE_CFG;
#if defined(SUPPORT_LINUX_DVFS)
typedef struct _IMG_DVFS_GOVERNOR_
{
IMG_BOOL bEnabled;
} IMG_DVFS_GOVERNOR;
typedef struct _IMG_DVFS_GOVERNOR_CFG_
{
IMG_UINT32 ui32UpThreshold;
IMG_UINT32 ui32DownDifferential;
} IMG_DVFS_GOVERNOR_CFG;
#endif
#if defined(__linux__)
#if defined(SUPPORT_LINUX_DVFS)
typedef struct _IMG_DVFS_DEVICE_
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
struct opp *psOPP;
#else
struct dev_pm_opp *psOPP;
#endif
struct devfreq *psDevFreq;
IMG_BOOL bInitPending;
IMG_BOOL bReady;
IMG_BOOL bEnabled;
IMG_HANDLE hGpuUtilUserDVFS;
struct devfreq_simple_ondemand_data data;
#if defined(CONFIG_DEVFREQ_THERMAL)
struct thermal_cooling_device *psDevfreqCoolingDevice;
#endif
} IMG_DVFS_DEVICE;
#endif
typedef struct _IMG_DVFS_
{
#if defined(SUPPORT_LINUX_DVFS)
IMG_DVFS_DEVICE sDVFSDevice;
IMG_DVFS_GOVERNOR sDVFSGovernor;
IMG_DVFS_GOVERNOR_CFG sDVFSGovernorCfg;
#endif
IMG_DVFS_DEVICE_CFG sDVFSDeviceCfg;
} PVRSRV_DVFS;
#endif/* (__linux__) */
#endif /* PVR_DVFS_H */

View File

@@ -0,0 +1,824 @@
/*************************************************************************/ /*!
@File
@Title PowerVR devfreq device implementation
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description Linux module setup
@License Dual MIT/GPLv2
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.
This License is also included in this distribution in the file called
"MIT-COPYING".
EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/
#if !defined(NO_HARDWARE)
#include <linux/devfreq.h>
#if defined(CONFIG_DEVFREQ_THERMAL)
#include <linux/devfreq_cooling.h>
#endif
#include <linux/version.h>
#include <linux/device.h>
#include <drm/drm.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
#include <drm/drm_device.h>
#include <drm/drm_file.h>
#else
#include <drm/drmP.h>
#endif
#include "power.h"
#include "pvrsrv.h"
#include "pvrsrv_device.h"
#include "rgxdevice.h"
#include "rgxinit.h"
#include "sofunc_rgx.h"
#include "syscommon.h"
#include "pvr_dvfs_device.h"
#include "kernel_compatibility.h"
static int _device_get_devid(struct device *dev)
{
struct drm_device *ddev = dev_get_drvdata(dev);
int deviceId;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0))
/*
* Older kernels do not have render drm_minor member in drm_device,
* so we fallback to primary node for device identification
*/
deviceId = ddev->primary->index;
#else
if (ddev->render)
deviceId = ddev->render->index;
else /* when render node is NULL, fallback to primary node */
deviceId = ddev->primary->index;
#endif
return deviceId;
}
static IMG_INT32 devfreq_target(struct device *dev, unsigned long *requested_freq, IMG_UINT32 flags)
{
int deviceId = _device_get_devid(dev);
PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId);
RGX_DATA *psRGXData = NULL;
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL;
RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL;
IMG_UINT32 ui32Freq, ui32CurFreq, ui32Volt;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
struct opp *opp;
#else
struct dev_pm_opp *opp;
#endif
/* Check the device is registered */
if (!psDeviceNode)
{
return -ENODEV;
}
psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
/* Check the RGX device is initialised */
if (!psRGXData)
{
return -ENODATA;
}
psRGXTimingInfo = psRGXData->psRGXTimingInfo;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
rcu_read_lock();
#endif
opp = devfreq_recommended_opp(dev, requested_freq, flags);
if (IS_ERR(opp)) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
rcu_read_unlock();
#endif
PVR_DPF((PVR_DBG_ERROR, "Invalid OPP"));
return PTR_ERR(opp);
}
ui32Freq = dev_pm_opp_get_freq(opp);
ui32Volt = dev_pm_opp_get_voltage(opp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
rcu_read_unlock();
#else
dev_pm_opp_put(opp);
#endif
ui32CurFreq = psRGXTimingInfo->ui32CoreClockSpeed;
if (ui32CurFreq == ui32Freq)
{
return 0;
}
if (psDeviceNode->eCurrentSysPowerState != PVRSRV_SYS_POWER_STATE_ON)
{
*requested_freq = psRGXTimingInfo->ui32CoreClockSpeed;
return 0;
}
if (PVRSRV_OK != PVRSRVDevicePreClockSpeedChange(psDeviceNode,
psDVFSDeviceCfg->bIdleReq,
NULL))
{
dev_err(dev, "PVRSRVDevicePreClockSpeedChange failed\n");
return -EPERM;
}
if (!psDVFSDevice->bEnabled)
{
*requested_freq = psRGXTimingInfo->ui32CoreClockSpeed;
goto ClockSpeedChangePost;
}
/* Increasing frequency, change voltage first */
if (ui32Freq > ui32CurFreq)
{
psDVFSDeviceCfg->pfnSetVoltage(ui32Volt);
}
psDVFSDeviceCfg->pfnSetFrequency(ui32Freq);
/* Decreasing frequency, change frequency first */
if (ui32Freq < ui32CurFreq)
{
psDVFSDeviceCfg->pfnSetVoltage(ui32Volt);
}
psRGXTimingInfo->ui32CoreClockSpeed = ui32Freq;
ClockSpeedChangePost:
PVRSRVDevicePostClockSpeedChange(psDeviceNode, psDVFSDeviceCfg->bIdleReq,
NULL);
return 0;
}
static int devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *stat)
{
int deviceId = _device_get_devid(dev);
PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId);
PVRSRV_RGXDEV_INFO *psDevInfo = NULL;
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
RGX_DATA *psRGXData = NULL;
RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL;
RGXFWIF_GPU_UTIL_STATS sGpuUtilStats;
PVRSRV_ERROR eError;
/* Check the device is registered */
if (!psDeviceNode)
{
return -ENODEV;
}
psDevInfo = psDeviceNode->pvDevice;
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
/* Check the RGX device is initialised */
if (!psDevInfo || !psRGXData)
{
return -ENODATA;
}
psRGXTimingInfo = psRGXData->psRGXTimingInfo;
stat->current_frequency = psRGXTimingInfo->ui32CoreClockSpeed;
if (psDevInfo->pfnGetGpuUtilStats == NULL)
{
/* Not yet ready. So set times to something sensible. */
stat->busy_time = 0;
stat->total_time = 0;
return 0;
}
eError = psDevInfo->pfnGetGpuUtilStats(psDeviceNode,
psDVFSDevice->hGpuUtilUserDVFS,
&sGpuUtilStats);
if (eError != PVRSRV_OK)
{
return -EAGAIN;
}
stat->busy_time = sGpuUtilStats.ui64GpuStatActive;
stat->total_time = sGpuUtilStats.ui64GpuStatCumulative;
return 0;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
static IMG_INT32 devfreq_cur_freq(struct device *dev, unsigned long *freq)
{
int deviceId = _device_get_devid(dev);
PVRSRV_DEVICE_NODE *psDeviceNode = PVRSRVGetDeviceInstanceByOSId(deviceId);
RGX_DATA *psRGXData = NULL;
/* Check the device is registered */
if (!psDeviceNode)
{
return -ENODEV;
}
psRGXData = (RGX_DATA*) psDeviceNode->psDevConfig->hDevData;
/* Check the RGX device is initialised */
if (!psRGXData)
{
return -ENODATA;
}
*freq = psRGXData->psRGXTimingInfo->ui32CoreClockSpeed;
return 0;
}
#endif
static struct devfreq_dev_profile img_devfreq_dev_profile =
{
.target = devfreq_target,
.get_dev_status = devfreq_get_dev_status,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
.get_cur_freq = devfreq_cur_freq,
#endif
};
static int FillOPPTable(struct device *dev, PVRSRV_DEVICE_NODE *psDeviceNode)
{
const IMG_OPP *iopp;
int i, err = 0;
IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL;
/* Check the device exists */
if (!dev || !psDeviceNode)
{
return -ENODEV;
}
psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
for (i = 0, iopp = psDVFSDeviceCfg->pasOPPTable;
i < psDVFSDeviceCfg->ui32OPPTableSize;
i++, iopp++)
{
err = dev_pm_opp_add(dev, iopp->ui32Freq, iopp->ui32Volt);
if (err) {
dev_err(dev, "Could not add OPP entry, %d\n", err);
return err;
}
}
return 0;
}
static void ClearOPPTable(struct device *dev, PVRSRV_DEVICE_NODE *psDeviceNode)
{
#if (defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))) || \
(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
const IMG_OPP *iopp;
int i;
IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL;
/* Check the device exists */
if (!dev || !psDeviceNode)
{
return;
}
psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
for (i = 0, iopp = psDVFSDeviceCfg->pasOPPTable;
i < psDVFSDeviceCfg->ui32OPPTableSize;
i++, iopp++)
{
dev_pm_opp_remove(dev, iopp->ui32Freq);
}
#endif
}
static int GetOPPValues(struct device *dev,
unsigned long *min_freq,
unsigned long *min_volt,
unsigned long *max_freq)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
struct opp *opp;
#else
struct dev_pm_opp *opp;
#endif
int count, i, err = 0;
unsigned long freq;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) && \
(!defined(CHROMIUMOS_KERNEL) || (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)))
unsigned int *freq_table;
#else
unsigned long *freq_table;
#endif
count = dev_pm_opp_get_opp_count(dev);
if (count < 0)
{
dev_err(dev, "Could not fetch OPP count, %d\n", count);
return count;
}
dev_info(dev, "Found %d OPP points.\n", count);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
freq_table = devm_kcalloc(dev, count, sizeof(*freq_table), GFP_ATOMIC);
#else
freq_table = kcalloc(count, sizeof(*freq_table), GFP_ATOMIC);
#endif
if (! freq_table)
{
return -ENOMEM;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
/* Start RCU read-side critical section to map frequency to OPP */
rcu_read_lock();
#endif
/* Iterate over OPP table; Iteration 0 finds "opp w/ freq >= 0 Hz". */
freq = 0;
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp))
{
err = PTR_ERR(opp);
dev_err(dev, "Couldn't find lowest frequency, %d\n", err);
goto exit;
}
*min_volt = dev_pm_opp_get_voltage(opp);
*max_freq = *min_freq = freq_table[0] = freq;
dev_info(dev, "opp[%d/%d]: (%lu Hz, %lu uV)\n", 1, count, freq, *min_volt);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
dev_pm_opp_put(opp);
#endif
/* Iteration i > 0 finds "opp w/ freq >= (opp[i-1].freq + 1)". */
for (i = 1; i < count; i++)
{
freq++;
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp))
{
err = PTR_ERR(opp);
dev_err(dev, "Couldn't find %dth frequency, %d\n", i, err);
goto exit;
}
freq_table[i] = freq;
*max_freq = freq;
dev_info(dev,
"opp[%d/%d]: (%lu Hz, %lu uV)\n",
i + 1,
count,
freq,
dev_pm_opp_get_voltage(opp));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
dev_pm_opp_put(opp);
#endif
}
exit:
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
rcu_read_unlock();
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
if (!err)
{
img_devfreq_dev_profile.freq_table = freq_table;
img_devfreq_dev_profile.max_state = count;
}
else
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
devm_kfree(dev, freq_table);
#else
kfree(freq_table);
#endif
}
return err;
}
#if defined(CONFIG_DEVFREQ_THERMAL)
static int RegisterCoolingDevice(struct device *dev,
IMG_DVFS_DEVICE *psDVFSDevice,
struct devfreq_cooling_power *powerOps)
{
struct device_node *of_node;
int err = 0;
PVRSRV_VZ_RET_IF_MODE(GUEST, err);
if (!psDVFSDevice)
{
return -EINVAL;
}
if (!powerOps)
{
dev_info(dev, "Cooling: power ops not registered, not enabling cooling");
return 0;
}
of_node = of_node_get(dev->of_node);
psDVFSDevice->psDevfreqCoolingDevice = of_devfreq_cooling_register_power(
of_node, psDVFSDevice->psDevFreq, powerOps);
if (IS_ERR(psDVFSDevice->psDevfreqCoolingDevice))
{
err = PTR_ERR(psDVFSDevice->psDevfreqCoolingDevice);
dev_err(dev, "Failed to register as devfreq cooling device %d", err);
}
of_node_put(of_node);
return err;
}
#endif
#define TO_IMG_ERR(err) ((err == -EPROBE_DEFER) ? PVRSRV_ERROR_PROBE_DEFER : PVRSRV_ERROR_INIT_FAILURE)
PVRSRV_ERROR InitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL;
struct device *psDev;
PVRSRV_ERROR eError;
int err;
PVRSRV_VZ_RET_IF_MODE(GUEST, PVRSRV_OK);
#if !defined(CONFIG_PM_OPP)
return PVRSRV_ERROR_NOT_SUPPORTED;
#endif
if (!psDeviceNode)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
if (psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending)
{
PVR_DPF((PVR_DBG_ERROR,
"DVFS initialise pending for device node %p",
psDeviceNode));
return PVRSRV_ERROR_INIT_FAILURE;
}
psDev = psDeviceNode->psDevConfig->pvOSDevice;
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending = IMG_TRUE;
#if defined(SUPPORT_SOC_TIMER)
if (! psDeviceNode->psDevConfig->pfnSoCTimerRead)
{
PVR_DPF((PVR_DBG_ERROR, "System layer SoC timer callback not implemented"));
return PVRSRV_ERROR_NOT_IMPLEMENTED;
}
#endif
eError = SORgxGpuUtilStatsRegister(&psDVFSDevice->hGpuUtilUserDVFS);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to register to the GPU utilisation stats, %d", eError));
return eError;
}
#if defined(CONFIG_OF)
err = dev_pm_opp_of_add_table(psDev);
if (err)
{
/*
* If there are no device tree or system layer provided operating points
* then return an error
*/
if (err != -ENODEV || !psDVFSDeviceCfg->pasOPPTable)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to init opp table from devicetree, %d", err));
eError = TO_IMG_ERR(err);
goto err_exit;
}
}
#endif
if (psDVFSDeviceCfg->pasOPPTable)
{
err = FillOPPTable(psDev, psDeviceNode);
if (err)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to fill OPP table with data, %d", err));
eError = TO_IMG_ERR(err);
goto err_exit;
}
}
PVR_TRACE(("PVR DVFS init pending: dev = %p, PVR device = %p",
psDev, psDeviceNode));
return PVRSRV_OK;
err_exit:
DeinitDVFS(psDeviceNode);
return eError;
}
PVRSRV_ERROR RegisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
IMG_DVFS_DEVICE_CFG *psDVFSDeviceCfg = NULL;
IMG_DVFS_GOVERNOR_CFG *psDVFSGovernorCfg = NULL;
RGX_TIMING_INFORMATION *psRGXTimingInfo = NULL;
struct device *psDev;
unsigned long min_freq = 0, max_freq = 0, min_volt = 0;
PVRSRV_ERROR eError;
int err;
if (!psDeviceNode)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
if (!psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending)
{
PVR_DPF((PVR_DBG_ERROR,
"DVFS initialise not yet pending for device node %p",
psDeviceNode));
return PVRSRV_ERROR_INIT_FAILURE;
}
psDev = psDeviceNode->psDevConfig->pvOSDevice;
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDVFSDeviceCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSDeviceCfg;
psDVFSGovernorCfg = &psDeviceNode->psDevConfig->sDVFS.sDVFSGovernorCfg;
psRGXTimingInfo = ((RGX_DATA *)psDeviceNode->psDevConfig->hDevData)->psRGXTimingInfo;
psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bInitPending = IMG_FALSE;
psDeviceNode->psDevConfig->sDVFS.sDVFSDevice.bReady = IMG_TRUE;
err = GetOPPValues(psDev, &min_freq, &min_volt, &max_freq);
if (err)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to read OPP points, %d", err));
eError = TO_IMG_ERR(err);
goto err_exit;
}
img_devfreq_dev_profile.initial_freq = min_freq;
img_devfreq_dev_profile.polling_ms = psDVFSDeviceCfg->ui32PollMs;
psRGXTimingInfo->ui32CoreClockSpeed = min_freq;
psDVFSDeviceCfg->pfnSetFrequency(min_freq);
psDVFSDeviceCfg->pfnSetVoltage(min_volt);
psDVFSDevice->data.upthreshold = psDVFSGovernorCfg->ui32UpThreshold;
psDVFSDevice->data.downdifferential = psDVFSGovernorCfg->ui32DownDifferential;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
psDVFSDevice->psDevFreq = devm_devfreq_add_device(psDev,
&img_devfreq_dev_profile,
"simple_ondemand",
&psDVFSDevice->data);
#else
psDVFSDevice->psDevFreq = devfreq_add_device(psDev,
&img_devfreq_dev_profile,
"simple_ondemand",
&psDVFSDevice->data);
#endif
if (IS_ERR(psDVFSDevice->psDevFreq))
{
PVR_DPF((PVR_DBG_ERROR,
"Failed to add as devfreq device %p, %ld",
psDVFSDevice->psDevFreq,
PTR_ERR(psDVFSDevice->psDevFreq)));
eError = TO_IMG_ERR(PTR_ERR(psDVFSDevice->psDevFreq));
goto err_exit;
}
eError = SuspendDVFS(psDeviceNode);
if (eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR, "PVRSRVInit: Failed to suspend DVFS"));
goto err_exit;
}
err = devfreq_suspend_device(psDVFSDevice->psDevFreq);
if (err < 0)
{
PVR_DPF((PVR_DBG_ERROR, "failed to suspend the devfreq devices"));
eError = TO_IMG_ERR(err);
goto err_exit;
}
#if defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
psDVFSDevice->psDevFreq->policy.user.min_freq = min_freq;
psDVFSDevice->psDevFreq->policy.user.max_freq = max_freq;
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
psDVFSDevice->psDevFreq->scaling_min_freq = min_freq;
psDVFSDevice->psDevFreq->scaling_max_freq = max_freq;
#else
psDVFSDevice->psDevFreq->min_freq = min_freq;
psDVFSDevice->psDevFreq->max_freq = max_freq;
#endif
err = devfreq_register_opp_notifier(psDev, psDVFSDevice->psDevFreq);
if (err)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to register opp notifier, %d", err));
eError = TO_IMG_ERR(err);
goto err_exit;
}
#if defined(CONFIG_DEVFREQ_THERMAL)
err = RegisterCoolingDevice(psDev, psDVFSDevice, psDVFSDeviceCfg->psPowerOps);
if (err)
{
eError = TO_IMG_ERR(err);
goto err_exit;
}
#endif
PVR_TRACE(("PVR DVFS activated: %lu-%lu Hz, Period: %ums",
min_freq,
max_freq,
psDVFSDeviceCfg->ui32PollMs));
return PVRSRV_OK;
err_exit:
UnregisterDVFSDevice(psDeviceNode);
return eError;
}
void UnregisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
struct device *psDev = NULL;
IMG_INT32 i32Error;
/* Check the device exists */
if (!psDeviceNode)
{
return;
}
PVRSRV_VZ_RETN_IF_MODE(GUEST);
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDev = psDeviceNode->psDevConfig->pvOSDevice;
if (! psDVFSDevice)
{
return;
}
#if defined(CONFIG_DEVFREQ_THERMAL)
if (!IS_ERR_OR_NULL(psDVFSDevice->psDevfreqCoolingDevice))
{
devfreq_cooling_unregister(psDVFSDevice->psDevfreqCoolingDevice);
psDVFSDevice->psDevfreqCoolingDevice = NULL;
}
#endif
if (psDVFSDevice->psDevFreq)
{
i32Error = devfreq_unregister_opp_notifier(psDev, psDVFSDevice->psDevFreq);
if (i32Error < 0)
{
PVR_DPF((PVR_DBG_ERROR, "Failed to unregister OPP notifier"));
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
devfreq_remove_device(psDVFSDevice->psDevFreq);
#else
devm_devfreq_remove_device(psDev, psDVFSDevice->psDevFreq);
#endif
psDVFSDevice->psDevFreq = NULL;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
kfree(img_devfreq_dev_profile.freq_table);
#endif
psDVFSDevice->bInitPending = IMG_FALSE;
psDVFSDevice->bReady = IMG_FALSE;
}
void DeinitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
struct device *psDev = NULL;
/* Check the device exists */
if (!psDeviceNode)
{
return;
}
PVRSRV_VZ_RETN_IF_MODE(GUEST);
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDev = psDeviceNode->psDevConfig->pvOSDevice;
/* Remove OPP entries for this device */
ClearOPPTable(psDev, psDeviceNode);
#if defined(CONFIG_OF)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) || \
(defined(CHROMIUMOS_KERNEL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)))
dev_pm_opp_of_remove_table(psDev);
#endif
#endif
SORgxGpuUtilStatsUnregister(psDVFSDevice->hGpuUtilUserDVFS);
psDVFSDevice->hGpuUtilUserDVFS = NULL;
psDVFSDevice->bInitPending = IMG_FALSE;
psDVFSDevice->bReady = IMG_FALSE;
}
PVRSRV_ERROR SuspendDVFS(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
/* Check the device is registered */
if (!psDeviceNode)
{
return PVRSRV_ERROR_INVALID_DEVICE;
}
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
psDVFSDevice->bEnabled = IMG_FALSE;
return PVRSRV_OK;
}
PVRSRV_ERROR ResumeDVFS(PPVRSRV_DEVICE_NODE psDeviceNode)
{
IMG_DVFS_DEVICE *psDVFSDevice = NULL;
/* Check the device is registered */
if (!psDeviceNode)
{
return PVRSRV_ERROR_INVALID_DEVICE;
}
psDVFSDevice = &psDeviceNode->psDevConfig->sDVFS.sDVFSDevice;
/* Not supported in GuestOS drivers */
psDVFSDevice->bEnabled = !PVRSRV_VZ_MODE_IS(GUEST);
return PVRSRV_OK;
}
#endif /* !NO_HARDWARE */

View File

@@ -0,0 +1,62 @@
/*************************************************************************/ /*!
@File pvr_dvfs.c
@Title System level interface for DVFS
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License Dual MIT/GPLv2
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.
This License is also included in this distribution in the file called
"MIT-COPYING".
EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/
#ifndef PVR_DVFS_DEVICE_H
#define PVR_DVFS_DEVICE_H
#include "opaque_types.h"
#include "pvrsrv_error.h"
PVRSRV_ERROR InitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode);
void DeinitDVFS(PPVRSRV_DEVICE_NODE psDeviceNode);
PVRSRV_ERROR RegisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode);
void UnregisterDVFSDevice(PPVRSRV_DEVICE_NODE psDeviceNode);
PVRSRV_ERROR SuspendDVFS(PPVRSRV_DEVICE_NODE psDeviceNode);
PVRSRV_ERROR ResumeDVFS(PPVRSRV_DEVICE_NODE psDeviceNode);
#endif /* PVR_DVFS_DEVICE_H */

View File

@@ -136,7 +136,8 @@ pvrsrvkm-y += \
dma_support.o \
vmm_type_stub.o \
sysconfig.o \
thead_sys.o
thead_sys.o \
pvr_dvfs_device.o
pvrsrvkm-$(CONFIG_DRM_POWERVR_ROGUE_DEBUG) += \
client_ri_direct_bridge.o \
server_ri_bridge.o \

View File

@@ -0,0 +1,95 @@
/*************************************************************************/ /*!
@File
@Title SO Interface header file for devices/RGX functions
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description Contains SO interface functions. These functions are defined in
the common devices layer and are called from the env layer OS
specific implementation.
@License Dual MIT/GPLv2
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.
If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.
This License is also included in this distribution in the file called
"MIT-COPYING".
EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/
#if !defined(SOFUNC_RGX_H_)
#define SOFUNC_RGX_H_
#include "img_types.h"
#include "pvrsrv_error.h"
#if !defined(NO_HARDWARE)
/*!
*******************************************************************************
@Function SORgxGpuUtilStatsRegister
@Description SO Interface function called from the OS layer implementation.
Initialise data used to compute GPU utilisation statistics
for a particular user (identified by the handle passed as
argument). This function must be called only once for each
different user/handle.
@Input phGpuUtilUser - Pointer to handle used to identify a user of
RGXGetGpuUtilStats
@Return PVRSRV_ERROR
******************************************************************************/
PVRSRV_ERROR SORgxGpuUtilStatsRegister(IMG_HANDLE *phGpuUtilUser);
/*!
*******************************************************************************
@Function SORgxGpuUtilStatsUnregister
@Description SO Interface function called from the OS layer implementation.
Free data previously used to compute GPU utilisation statistics
for a particular user (identified by the handle passed as
argument).
@Input hGpuUtilUser - Handle used to identify a user of
RGXGetGpuUtilStats
@Return PVRSRV_ERROR
******************************************************************************/
PVRSRV_ERROR SORgxGpuUtilStatsUnregister(IMG_HANDLE hGpuUtilUser);
#endif /* !defined(NO_HARDWARE) */
#endif /* SOFUNC_RGX_H_ */

View File

@@ -193,27 +193,6 @@ static int vs_plane_atomic_get_property(struct drm_plane *plane,
return 0;
}
static bool vs_plane_format_mod_supported(struct drm_plane *plane,
uint32_t format,
uint64_t modifier)
{
struct vs_plane *vs_plane = to_vs_plane(plane);
int i;
for(i = 0; i < vs_plane->info->num_modifiers; i++) {
if (vs_plane->info->modifiers[i] == modifier)
break;
}
if (i && i == vs_plane->info->num_modifiers)
return false;
for(i = 0; i < vs_plane->info->num_formats; i++) {
if (vs_plane->info->formats[i] == format)
return true;
}
return false;
}
const struct drm_plane_funcs vs_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -223,7 +202,6 @@ const struct drm_plane_funcs vs_plane_funcs = {
.atomic_destroy_state = vs_plane_atomic_destroy_state,
.atomic_set_property = vs_plane_atomic_set_property,
.atomic_get_property = vs_plane_atomic_get_property,
.format_mod_supported = vs_plane_format_mod_supported,
};
static unsigned char vs_get_plane_number(struct drm_framebuffer *fb)
@@ -322,8 +300,6 @@ struct vs_plane *vs_plane_create(struct drm_device *drm_dev,
if (!plane)
return NULL;
plane->info = info;
ret = drm_universal_plane_init(drm_dev, &plane->base, possible_crtcs,
&vs_plane_funcs, info->formats,
info->num_formats, info->modifiers, info->type,

View File

@@ -47,7 +47,6 @@ struct vs_plane {
struct drm_plane base;
u8 id;
dma_addr_t dma_addr[MAX_NUM_PLANES];
struct vs_plane_info *info;
struct drm_property *degamma_mode;
struct drm_property *watermark_prop;

View File

@@ -868,9 +868,6 @@ static int __maybe_unused thead_dwmac_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
pm_debug(dev,"enter %s()\n",__func__);
if (!netif_running(ndev))
return 0;
if (priv->plat->init)
priv->plat->init(pdev, priv->plat->bsp_priv);

View File

@@ -22,12 +22,6 @@ config LIGHT_REBOOTMODE
help
This driver supports check rebootmode feature in Light FM platform
config LIGHT_DDR_PMU
tristate "Thead light ddr-pmu support"
default m
help
This driver supports thead-ddr-pmu is a IP module used to do performance monitor
endmenu
endif

View File

@@ -2,4 +2,3 @@
obj-$(CONFIG_LIGHT_IOPMP) += light-iopmp.o
obj-$(CONFIG_LIGHT_SUSPEND) += pm-light.o
obj-$(CONFIG_LIGHT_REBOOTMODE) += light_event.o
obj-$(CONFIG_LIGHT_DDR_PMU) += thead-ddr-pmu.o

File diff suppressed because it is too large Load Diff

View File

@@ -317,9 +317,6 @@ endif
DTC ?= $(objtree)/scripts/dtc/dtc
DTC_FLAGS += $(call dtc-option,-Wno-interrupt_provider)
# Overlay support
DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)
DTC_FLAGS += $(call dtc-option,-Wno-unit_address_vs_reg) \

View File

@@ -112,7 +112,7 @@ dbg_dir=debian/linux-image-dbg
perf_dir="$objtree/debian/toolstmp"
packagename=linux-image-$version
dbg_packagename=$packagename-dbg
perf_packagename=linux-perf-vendor-th1520
perf_packagename=linux-perf-thead
if [ "$ARCH" = "um" ] ; then
packagename=user-mode-linux-$version
@@ -257,7 +257,7 @@ Description: Performance analysis tools for Linux $version
kernel version $version .
EOF
mv $tools_dest/usr/bin/perf $tools_dest/usr/bin/perf-vendor-th1520
mv $tools_dest/usr/bin/perf $tools_dest/usr/bin/perf-thead
dpkg-shlibdeps $tools_dest/usr/bin/*
create_package "$perf_packagename" "$perf_dir"
fi