linux: update rockchip-4.4 to 7b43537e

This commit is contained in:
Jonas Karlman 2018-02-11 23:00:03 +01:00
parent d223852f1b
commit 58a858b3e8
16 changed files with 10289 additions and 6875 deletions

View File

@ -47,8 +47,8 @@ case "$LINUX" in
PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET aml-dtbtools:host"
;;
rockchip-4.4)
PKG_VERSION="28018092"
PKG_SHA256="944b59f3b8fd9c1e37ea717e600651f9e49f3f01e2e9290d00386dec1789bf83"
PKG_VERSION="7b43537e"
PKG_SHA256="f934e8364308388868edd8d89f6fa71af8516a9b25bfaa1451bdc1b473735fdc"
PKG_URL="https://github.com/rockchip-linux/kernel/archive/$PKG_VERSION.tar.gz"
PKG_SOURCE_DIR="kernel-$PKG_VERSION*"
PKG_PATCH_DIRS="rockchip-4.4"

View File

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 4.4.103 Kernel Configuration
# Linux/arm64 4.4.112 Kernel Configuration
#
CONFIG_ARM64=y
CONFIG_64BIT=y
@ -458,6 +458,7 @@ CONFIG_SECCOMP=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_XEN is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_UNMAP_KERNEL_AT_EL0=y
# CONFIG_ARMV8_DEPRECATED is not set
# CONFIG_ARM64_SW_TTBR0_PAN is not set
@ -1686,6 +1687,7 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
# CONFIG_TOUCHSCREEN_GSLX680_VR is not set
# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
# CONFIG_TOUCHSCREEN_GT9XX is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
@ -1736,6 +1738,7 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_VTL_CT36X is not set
# CONFIG_TOUCHSCREEN_GT1X is not set
# CONFIG_ROCKCHIP_REMOTECTL is not set
#
@ -2376,6 +2379,7 @@ CONFIG_MFD_CROS_EC_SPI=y
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RTSX_USB is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK618 is not set
CONFIG_MFD_RK808=y
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_CORE is not set
@ -2598,14 +2602,15 @@ CONFIG_DRM_BRIDGE=y
#
# Display Interface Bridges
#
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
# CONFIG_DRM_DUMB_VGA_DAC is not set
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_DW_HDMI=y
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
CONFIG_DRM_DW_HDMI_CEC=y
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
CONFIG_DRM_ANALOGIX_DP=y
# CONFIG_POWERVR_ROGUE_M is not set
CONFIG_MALI400=m
CONFIG_MALI450=y
@ -2873,6 +2878,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS4349 is not set
# CONFIG_SND_SOC_CX2072X is not set
# CONFIG_SND_SOC_CX20810 is not set
# CONFIG_SND_SOC_BT_SCO is not set
CONFIG_SND_SOC_ES8316=y
# CONFIG_SND_SOC_ES8323 is not set
@ -3323,6 +3329,8 @@ CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_EMBEDDED_SDIO is not set
# CONFIG_MMC_PARANOID_SD_INIT is not set
CONFIG_PWRSEQ_EMMC=y
CONFIG_PWRSEQ_SIMPLE=y
#
# MMC/SD/SDIO Card Drivers
@ -3721,6 +3729,7 @@ CONFIG_CLKSRC_PROBE=y
CONFIG_ROCKCHIP_TIMER=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
# CONFIG_ARM_TIMER_SP804 is not set
# CONFIG_ATMEL_PIT is not set
# CONFIG_SH_TIMER_CMT is not set
@ -3783,10 +3792,10 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y
#
# DEVFREQ Drivers
#
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
# CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI is not set
# CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP is not set
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
CONFIG_EXTCON=y
#

View File

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 4.4.103 Kernel Configuration
# Linux/arm 4.4.112 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_ARM_HAS_SG_CHAIN=y
@ -1582,6 +1582,7 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
# CONFIG_TOUCHSCREEN_GSLX680_VR is not set
# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
# CONFIG_TOUCHSCREEN_GT9XX is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
@ -1632,6 +1633,7 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_VTL_CT36X is not set
# CONFIG_TOUCHSCREEN_GT1X is not set
# CONFIG_ROCKCHIP_REMOTECTL is not set
#
@ -2221,6 +2223,7 @@ CONFIG_MFD_CROS_EC_SPI=y
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RTSX_USB is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK618 is not set
CONFIG_MFD_RK808=y
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_CORE is not set
@ -2434,14 +2437,15 @@ CONFIG_DRM_BRIDGE=y
#
# Display Interface Bridges
#
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
# CONFIG_DRM_DUMB_VGA_DAC is not set
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_DW_HDMI=y
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
# CONFIG_DRM_DW_HDMI_CEC is not set
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
CONFIG_DRM_ANALOGIX_DP=y
# CONFIG_DRM_STI is not set
# CONFIG_POWERVR_ROGUE_M is not set
# CONFIG_MALI400 is not set
@ -2688,6 +2692,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS4349 is not set
# CONFIG_SND_SOC_CX2072X is not set
# CONFIG_SND_SOC_CX20810 is not set
# CONFIG_SND_SOC_BT_SCO is not set
# CONFIG_SND_SOC_ES8316 is not set
CONFIG_SND_SOC_ES8323=y
@ -3115,6 +3120,8 @@ CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_EMBEDDED_SDIO is not set
# CONFIG_MMC_PARANOID_SD_INIT is not set
CONFIG_PWRSEQ_EMMC=y
CONFIG_PWRSEQ_SIMPLE=y
#
# MMC/SD/SDIO Card Drivers
@ -3499,6 +3506,7 @@ CONFIG_DW_APB_TIMER_OF=y
CONFIG_ROCKCHIP_TIMER=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y
CONFIG_ARM_GLOBAL_TIMER=y
# CONFIG_ARM_TIMER_SP804 is not set
CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
@ -3557,8 +3565,10 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y
#
# DEVFREQ Drivers
#
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
# CONFIG_EXTCON is not set
CONFIG_MEMORY=y
# CONFIG_ARM_PL172_MPMC is not set

View File

@ -1,7 +1,7 @@
From 0d7fc599ad0450f8f8581b66dc77df80bb2ba6b9 Mon Sep 17 00:00:00 2001
From 61d54b00c343c81af975a9742c17a01e4c343a31 Mon Sep 17 00:00:00 2001
From: Ziyuan Xu <xzy.xu@rock-chips.com>
Date: Fri, 23 Sep 2016 13:43:18 +0800
Subject: [PATCH 1/5] MINIARM: HACK: switch vccio_sd to 3.3v while shutdowning
Subject: [PATCH] MINIARM: HACK: switch vccio_sd to 3.3v while shutdowning
Change-Id: I80d6d2b61b31f16b6b42b9ffcaab077231a7a91c
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
@ -46,11 +46,11 @@ index 29e3ae99edbc..531ad93ff912 100644
.name = "dwmmc_rockchip",
.of_match_table = dw_mci_rockchip_match,
From fe3a39115dbd63aee25d3aec6d46e4aed4f8faeb Mon Sep 17 00:00:00 2001
From 834b425c19718d57c528806800a90ea0ac528472 Mon Sep 17 00:00:00 2001
From: Ziyuan Xu <xzy.xu@rock-chips.com>
Date: Mon, 6 Feb 2017 08:39:46 +0800
Subject: [PATCH 2/5] MINIARM: HACK: mmc: dw_mmc-rockchip: enable vmmc supply
for reboot
Subject: [PATCH] MINIARM: HACK: mmc: dw_mmc-rockchip: enable vmmc supply for
reboot
Mmc core has already power off the vmmc since shutdown, re-enable it so
that card is active in next reboot.
@ -87,10 +87,10 @@ index 531ad93ff912..eae304077e17 100644
if (!IS_ERR(mmc->supply.vqmmc))
regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000);
From d1a6f5f0e4103138b4ef21bf89a54c90ba022bb9 Mon Sep 17 00:00:00 2001
From ae8ebf01d7ff8e736cf85a720597ca9c94a1709a Mon Sep 17 00:00:00 2001
From: Jacob Chen <jacob-chen@iotwrt.com>
Date: Sat, 22 Jul 2017 19:55:09 +0800
Subject: [PATCH 3/5] MINIARM: drm/rockchip: update phy settings
Subject: [PATCH] MINIARM: drm/rockchip: update phy settings
Change-Id: I9e92a4191115e13999183a5d7656d6708adda632
Signed-off-by: Jacob Chen <jacob-chen@iotwrt.com>
@ -99,10 +99,10 @@ Signed-off-by: Jacob Chen <jacob-chen@iotwrt.com>
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index b3b6fd7ed698..7b13c633e28f 100644
index 257d0d0dcc3d..0c66a27bea93 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -343,8 +343,7 @@ static struct dw_hdmi_phy_config rockchip_phy_config[] = {
@@ -345,8 +345,7 @@ static struct dw_hdmi_phy_config rockchip_phy_config[] = {
/*pixelclk symbol term vlev*/
{ 74250000, 0x8009, 0x0004, 0x0272},
{ 165000000, 0x802b, 0x0004, 0x0209},
@ -113,10 +113,10 @@ index b3b6fd7ed698..7b13c633e28f 100644
};
From e47a2375fceb317e4be6e6f6c83a4ec0ff7ad05c Mon Sep 17 00:00:00 2001
From 79fb3a561bf55774b571c737537cada202f78044 Mon Sep 17 00:00:00 2001
From: Nickey Yang <nickey.yang@rock-chips.com>
Date: Mon, 17 Jul 2017 16:35:34 +0800
Subject: [PATCH 4/5] MINIARM: set npll be used for hdmi only
Subject: [PATCH] MINIARM: set npll be used for hdmi only
Change-Id: I8bebfb2cfb68e3dad172e5547d3886526ad5e912
Signed-off-by: Nickey Yang <nickey.yang@rock-chips.com>
@ -126,10 +126,10 @@ Signed-off-by: Nickey Yang <nickey.yang@rock-chips.com>
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 026288e9a2c9..7660a5e6ee95 100644
index 0af92bd2a723..70f8a69cc9bd 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -979,7 +979,7 @@
@@ -1027,7 +1027,7 @@
<&cru PCLK_PERI>;
assigned-clock-rates = <594000000>,
<500000000>, <300000000>,
@ -138,7 +138,7 @@ index 026288e9a2c9..7660a5e6ee95 100644
<300000000>, <150000000>,
<75000000>;
};
@@ -1201,6 +1201,8 @@
@@ -1265,6 +1265,8 @@
resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>;
reset-names = "axi", "ahb", "dclk";
iommus = <&vopb_mmu>;
@ -148,7 +148,7 @@ index 026288e9a2c9..7660a5e6ee95 100644
vopb_out: port {
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index aedbb038c707..46bb0ae76839 100644
index 72797f9479db..f79ebd843379 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -211,9 +211,9 @@ static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = {
@ -173,17 +173,17 @@ index aedbb038c707..46bb0ae76839 100644
RK3288_CLKGATE_CON(3), 1, GFLAGS),
COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0,
From 6b9c7604687e5dac7116a40179228be268ea9067 Mon Sep 17 00:00:00 2001
From 559fff078aedf673e1e4e191ec9a5eddc2a87f88 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 11 Dec 2017 23:09:54 +0100
Subject: [PATCH 5/5] clk: rockchip: rk3288: add more pixel clock rates
Subject: [PATCH] clk: rockchip: rk3288: add more pixel clock rates
---
drivers/clk/rockchip/clk-rk3288.c | 79 +++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 46bb0ae76839..848025559aa8 100644
index f79ebd843379..412a0165ec57 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -84,23 +84,94 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {

View File

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 4.4.103 Kernel Configuration
# Linux/arm64 4.4.112 Kernel Configuration
#
CONFIG_ARM64=y
CONFIG_64BIT=y
@ -458,6 +458,7 @@ CONFIG_SECCOMP=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_XEN is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_UNMAP_KERNEL_AT_EL0=y
# CONFIG_ARMV8_DEPRECATED is not set
# CONFIG_ARM64_SW_TTBR0_PAN is not set
@ -1533,15 +1534,15 @@ CONFIG_RT2X00_LIB_LEDS=y
# CONFIG_RTL_CARDS is not set
# CONFIG_RTL8XXXU is not set
CONFIG_WL_ROCKCHIP=y
# CONFIG_WIFI_BUILD_MODULE is not set
CONFIG_WIFI_BUILD_MODULE=y
# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set
# CONFIG_AP6XXX is not set
CONFIG_AP6XXX=m
CONFIG_RTL_WIRELESS_SOLUTION=y
# CONFIG_RTL8188EU is not set
# CONFIG_RTL8188FU is not set
# CONFIG_RTL8189ES is not set
# CONFIG_RTL8189FS is not set
# CONFIG_RTL8723BS is not set
CONFIG_RTL8189FS=m
CONFIG_RTL8723BS=m
# CONFIG_RTL8723BU is not set
# CONFIG_RTL8723CS is not set
# CONFIG_RTL8723DS is not set
@ -1686,6 +1687,7 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
# CONFIG_TOUCHSCREEN_GSLX680_VR is not set
# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
# CONFIG_TOUCHSCREEN_GT9XX is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
@ -1736,6 +1738,7 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_VTL_CT36X is not set
# CONFIG_TOUCHSCREEN_GT1X is not set
# CONFIG_ROCKCHIP_REMOTECTL is not set
#
@ -2376,6 +2379,7 @@ CONFIG_MFD_CROS_EC_SPI=y
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RTSX_USB is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK618 is not set
CONFIG_MFD_RK808=y
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_CORE is not set
@ -2598,14 +2602,15 @@ CONFIG_DRM_BRIDGE=y
#
# Display Interface Bridges
#
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
# CONFIG_DRM_DUMB_VGA_DAC is not set
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_DW_HDMI=y
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
CONFIG_DRM_DW_HDMI_CEC=y
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
CONFIG_DRM_ANALOGIX_DP=y
# CONFIG_POWERVR_ROGUE_M is not set
CONFIG_MALI400=m
CONFIG_MALI450=y
@ -2873,6 +2878,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS4349 is not set
# CONFIG_SND_SOC_CX2072X is not set
# CONFIG_SND_SOC_CX20810 is not set
# CONFIG_SND_SOC_BT_SCO is not set
CONFIG_SND_SOC_ES8316=y
# CONFIG_SND_SOC_ES8323 is not set
@ -3323,6 +3329,8 @@ CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_EMBEDDED_SDIO is not set
# CONFIG_MMC_PARANOID_SD_INIT is not set
CONFIG_PWRSEQ_EMMC=y
CONFIG_PWRSEQ_SIMPLE=y
#
# MMC/SD/SDIO Card Drivers
@ -3721,6 +3729,7 @@ CONFIG_CLKSRC_PROBE=y
CONFIG_ROCKCHIP_TIMER=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
# CONFIG_ARM_TIMER_SP804 is not set
# CONFIG_ATMEL_PIT is not set
# CONFIG_SH_TIMER_CMT is not set
@ -3783,10 +3792,10 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y
#
# DEVFREQ Drivers
#
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
# CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI is not set
# CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP is not set
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
CONFIG_EXTCON=y
#

View File

@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm 4.4.103 Kernel Configuration
# Linux/arm 4.4.112 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_ARM_HAS_SG_CHAIN=y
@ -1431,15 +1431,15 @@ CONFIG_RT2X00_LIB_LEDS=y
# CONFIG_RTL_CARDS is not set
# CONFIG_RTL8XXXU is not set
CONFIG_WL_ROCKCHIP=y
# CONFIG_WIFI_BUILD_MODULE is not set
CONFIG_WIFI_BUILD_MODULE=y
# CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set
# CONFIG_AP6XXX is not set
CONFIG_AP6XXX=m
CONFIG_RTL_WIRELESS_SOLUTION=y
# CONFIG_RTL8188EU is not set
# CONFIG_RTL8188FU is not set
# CONFIG_RTL8189ES is not set
# CONFIG_RTL8189FS is not set
# CONFIG_RTL8723BS is not set
CONFIG_RTL8723BS=m
# CONFIG_RTL8723BU is not set
# CONFIG_RTL8723CS is not set
# CONFIG_RTL8723DS is not set
@ -1582,6 +1582,7 @@ CONFIG_TOUCHSCREEN_ATMEL_MXT=y
# CONFIG_TOUCHSCREEN_GSLX680_VR is not set
# CONFIG_TOUCHSCREEN_GSLX680_FIREFLY is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSL3673_800X1280 is not set
# CONFIG_TOUCHSCREEN_GT9XX is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
@ -1632,6 +1633,7 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_VTL_CT36X is not set
# CONFIG_TOUCHSCREEN_GT1X is not set
# CONFIG_ROCKCHIP_REMOTECTL is not set
#
@ -2221,6 +2223,7 @@ CONFIG_MFD_CROS_EC_SPI=y
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RTSX_USB is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK618 is not set
CONFIG_MFD_RK808=y
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_CORE is not set
@ -2434,14 +2437,15 @@ CONFIG_DRM_BRIDGE=y
#
# Display Interface Bridges
#
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
# CONFIG_DRM_DUMB_VGA_DAC is not set
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_DW_HDMI=y
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
# CONFIG_DRM_DW_HDMI_CEC is not set
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_RK1000 is not set
CONFIG_DRM_ANALOGIX_DP=y
# CONFIG_DRM_STI is not set
# CONFIG_POWERVR_ROGUE_M is not set
# CONFIG_MALI400 is not set
@ -2688,6 +2692,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS4349 is not set
# CONFIG_SND_SOC_CX2072X is not set
# CONFIG_SND_SOC_CX20810 is not set
# CONFIG_SND_SOC_BT_SCO is not set
# CONFIG_SND_SOC_ES8316 is not set
CONFIG_SND_SOC_ES8323=y
@ -3115,6 +3120,8 @@ CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_EMBEDDED_SDIO is not set
# CONFIG_MMC_PARANOID_SD_INIT is not set
CONFIG_PWRSEQ_EMMC=y
CONFIG_PWRSEQ_SIMPLE=y
#
# MMC/SD/SDIO Card Drivers
@ -3499,6 +3506,7 @@ CONFIG_DW_APB_TIMER_OF=y
CONFIG_ROCKCHIP_TIMER=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_ARCH_TIMER_VCT_ACCESS=y
CONFIG_ARM_GLOBAL_TIMER=y
# CONFIG_ARM_TIMER_SP804 is not set
CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
@ -3557,8 +3565,10 @@ CONFIG_DEVFREQ_GOV_USERSPACE=y
#
# DEVFREQ Drivers
#
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y
CONFIG_PM_DEVFREQ_EVENT=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI=y
CONFIG_DEVFREQ_EVENT_ROCKCHIP_NOCP=y
# CONFIG_EXTCON is not set
CONFIG_MEMORY=y
# CONFIG_ARM_PL172_MPMC is not set

View File

@ -1,7 +1,35 @@
From a91ba53b3b923f767aa500c2209ebeae364a1f4e Mon Sep 17 00:00:00 2001
From 7ed1ed35ede3d6a5ad864924f65de15910690140 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Date: Thu, 19 Nov 2015 11:41:36 -0200
Subject: [PATCH] UPSTREAM: smsir.h: remove a now duplicated definition
(IR_DEFAULT_TIMEOUT)
This macro is now part of the core. Remove from Siano driver.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
(cherry picked from commit 850c8a7d68a761b5f11d5b443b5ece185e8068f4)
---
drivers/media/common/siano/smsir.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index fc8b7925c532..d9abd96ef48b 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/input.h>
#include <media/rc-core.h>
-#define IR_DEFAULT_TIMEOUT 100
-
struct smscore_device_t;
struct ir_t {
From ae4106c9f6587e5bcbd414c1df4b59bf6a009794 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH 1/7] [media] rc/keymaps: add keytable for Pine64 IR Remote
Subject: [PATCH] [media] rc/keymaps: add keytable for Pine64 IR Remote
Controller
---
@ -107,52 +135,10 @@ index 7c4bbc4dfab4..3a34a9631dd1 100644
#define RC_MAP_PINNACLE_GREY "rc-pinnacle-grey"
#define RC_MAP_PINNACLE_PCTV_HD "rc-pinnacle-pctv-hd"
From 6779fbca58a5e13f58b0ab1b68aabcc240631c1b Mon Sep 17 00:00:00 2001
From d8df6397a5a354ff41e25d93a625fe517ec5d5a4 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH 2/7] arm64: dts: rockchip: rk3328-rock64: add ir-receiver
---
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
index f2e3358a119b..28528e0ad926 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
@@ -70,6 +70,14 @@
#clock-cells = <0>;
};
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+ linux,rc-map-name = "rc-pine64";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
leds {
compatible = "gpio-leds";
@@ -489,6 +497,12 @@
<2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */
};
};
+
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&rkvdec {
From 090e35d622cd9d8280c86fe5f199558d7e4918a3 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH 3/7] [media] rc/keymaps: add keytable for ODROID IR Remote
Subject: [PATCH] [media] rc/keymaps: add keytable for ODROID IR Remote
Controller
---
@ -245,10 +231,10 @@ index 3a34a9631dd1..f1badbfbca90 100644
#define RC_MAP_PINE64 "rc-pine64"
#define RC_MAP_PINNACLE_COLOR "rc-pinnacle-color"
From 6f7300964103c68af09ba550844974369e8d6738 Mon Sep 17 00:00:00 2001
From a256d6c59814dcdd1489c82368bb9e9937f11408 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH 4/7] [media] rc/keymaps: add keytable for WeTek Hub Remote
Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Hub Remote
Controller
---
@ -341,10 +327,10 @@ index f1badbfbca90..cd8590c99e22 100644
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
From fd26a6d33798774bef4a757eec1f3de8eba5235c Mon Sep 17 00:00:00 2001
From def6431495bad6e916a10ce9ddfc5f4b3597422a Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Wed, 6 Sep 2017 18:39:09 +0200
Subject: [PATCH 5/7] [media] rc/keymaps: add keytable for WeTek Play 2 Remote
Subject: [PATCH] [media] rc/keymaps: add keytable for WeTek Play 2 Remote
Controller
---
@ -467,73 +453,3 @@ index cd8590c99e22..93cac05a5170 100644
#define RC_MAP_VIDEOMATE_K100 "rc-videomate-k100"
#define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350"
#define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr"
From 0136a4003d867331afacd22d182ff444da2c5495 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Mon, 30 Oct 2017 23:47:18 +0100
Subject: [PATCH 6/7] arm64: dts: rockchip: rk3328-rockbox: add ir-receiver
---
arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts
index 8ac8a8cc04ed..17ba816dc049 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rockbox.dts
@@ -84,6 +84,14 @@
reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
};
+ ir: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+ linux,rc-map-name = "rc-pine64";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_int>;
+ };
+
leds {
compatible = "gpio-leds";
@@ -414,6 +422,12 @@
};
};
+ ir {
+ ir_int: ir-int {
+ rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
sdio-pwrseq {
wifi_enable_h: wifi-enable-h {
rockchip,pins =
From 5e5a04d8a759f3799c9a623e4a41073091147d8e Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Date: Thu, 19 Nov 2015 11:41:36 -0200
Subject: [PATCH 7/7] UPSTREAM: smsir.h: remove a now duplicated definition
(IR_DEFAULT_TIMEOUT)
This macro is now part of the core. Remove from Siano driver.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
(cherry picked from commit 850c8a7d68a761b5f11d5b443b5ece185e8068f4)
---
drivers/media/common/siano/smsir.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index fc8b7925c532..d9abd96ef48b 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/input.h>
#include <media/rc-core.h>
-#define IR_DEFAULT_TIMEOUT 100
-
struct smscore_device_t;
struct ir_t {

View File

@ -1,17 +1,17 @@
From 3b22d9e27321d9c4bb601bd859029d4ce62bd49b Mon Sep 17 00:00:00 2001
From 23c1ed00568676ff958024283024a30b0c37565b Mon Sep 17 00:00:00 2001
From: LongChair <LongChair@hotmail.com>
Date: Sun, 26 Mar 2017 15:30:16 +0200
Subject: [PATCH 1/2] drm/rockchip: make video overlay bottom layer
Subject: [PATCH] drm/rockchip: make video overlay bottom layer
---
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 9d92b9a55e67..833498ed6915 100644
index d626acf00f10..2b0c739ade64 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -281,9 +281,9 @@ static const struct vop_ctrl rk3288_ctrl_data = {
@@ -283,9 +283,9 @@ static const struct vop_ctrl rk3288_ctrl_data = {
*/
static const struct vop_win_data rk3288_vop_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
@ -23,7 +23,7 @@ index 9d92b9a55e67..833498ed6915 100644
{ .base = 0x00, .phy = &rk3288_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY,
.area = rk3288_area_data,
@@ -974,10 +974,10 @@ static const struct vop_csc rk3328_win2_csc = {
@@ -988,10 +988,10 @@ static const struct vop_csc rk3328_win2_csc = {
static const struct vop_win_data rk3328_vop_win_data[] = {
{ .base = 0xd0, .phy = &rk3288_win01_data, .csc = &rk3328_win0_csc,
@ -37,11 +37,10 @@ index 9d92b9a55e67..833498ed6915 100644
{ .base = 0x2d0, .phy = &rk3288_win01_data, .csc = &rk3328_win2_csc,
.type = DRM_PLANE_TYPE_CURSOR,
From 04759d88467419ab1500908a909ed1775455b84d Mon Sep 17 00:00:00 2001
From dfed31cd9c52c004a51ac4e673e2746aeb0977fa Mon Sep 17 00:00:00 2001
From: LongChair <LongChair@hotmail.com>
Date: Mon, 24 Apr 2017 09:48:54 +0200
Subject: [PATCH 2/2] drm : allow framebuffer and videomodes not to have same
size
Subject: [PATCH] drm : allow framebuffer and videomodes not to have same size
DRM legacy doesn't allow that, will be only available with drm atomic.
Although, when running 4K modes, it's preferable to get a 1080p frambuffer that can be handlded properly by GPU and then use VOP to upscale that to 4K.
@ -51,10 +50,10 @@ Although, when running 4K modes, it's preferable to get a 1080p frambuffer that
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 9a513abd8a47..193997a5c640 100644
index f77d4aa1e58b..e611f93a80d6 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2208,11 +2208,11 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
@@ -2210,11 +2210,11 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
primary_state->src_x = set->x << 16;
primary_state->src_y = set->y << 16;
if (primary_state->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,870 @@
From 8c15967b21f2caf9897b1c4fa6c80b5de07aa7d0 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Fri, 25 Nov 2016 14:12:01 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix enabling of the TX-delay for
RTL8211F
The old logic always enabled the TX-delay when the phy-mode was set to
PHY_INTERFACE_MODE_RGMII. There are dedicated phy-modes which tell the
PHY driver to enable the RX and/or TX delays:
- PHY_INTERFACE_MODE_RGMII should disable the RX and TX delay in the
PHY (if required, the MAC should add the delays in this case)
- PHY_INTERFACE_MODE_RGMII_ID should enable RX and TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_TXID should enable the TX delay in the PHY
- PHY_INTERFACE_MODE_RGMII_RXID should enable the RX delay in the PHY
(currently not supported by RTL8211F)
With this patch we enable the TX delay for PHY_INTERFACE_MODE_RGMII_ID
and PHY_INTERFACE_MODE_RGMII_TXID.
Additionally we now explicity disable the TX-delay, which seems to be
enabled automatically after a hard-reset of the PHY (by triggering it's
reset pin) to get a consistent state (as defined by the phy-mode).
This fixes a compatibility problem with some SoCs where the TX-delay was
also added by the MAC. With the TX-delay being applied twice the TX
clock was off and TX traffic was broken or very slow (<10Mbit/s) on
1000Mbit/s links.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit e3230494b57ece68750e3e32d3e53d6b00917058)
---
drivers/net/phy/realtek.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 43ab691362d4..686f3b259dc0 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
- /* enable TXDLY */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
- reg = phy_read(phydev, 0x11);
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+ reg = phy_read(phydev, 0x11);
+
+ /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
reg |= RTL8211F_TX_DELAY;
- phy_write(phydev, 0x11, reg);
- /* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
- }
+ else
+ reg &= ~RTL8211F_TX_DELAY;
+
+ phy_write(phydev, 0x11, reg);
+ /* restore to default page 0 */
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
return 0;
}
From b3a985bdb18be879aa7a8ffe7fd9d7f1ee7a201d Mon Sep 17 00:00:00 2001
From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Date: Tue, 12 Sep 2017 18:54:35 +0900
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL8211F_PAGE_SELECT to
RTL821x_PAGE_SELECT
This renames the definition of page select register from
RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT to use it across models.
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 013955a6556766a76f9f2cc31e740fc6db6ecff4)
---
drivers/net/phy/realtek.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 686f3b259dc0..d58cc8f518ac 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -22,11 +22,11 @@
#define RTL821x_INER 0x12
#define RTL821x_INER_INIT 0x6400
#define RTL821x_INSR 0x13
+#define RTL821x_PAGE_SELECT 0x1f
#define RTL8211E_INER_LINK_STATUS 0x400
#define RTL8211F_INER_LINK_STATUS 0x0010
#define RTL8211F_INSR 0x1d
-#define RTL8211F_PAGE_SELECT 0x1f
#define RTL8211F_TX_DELAY 0x100
MODULE_DESCRIPTION("Realtek PHY driver");
@@ -46,10 +46,10 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
err = phy_read(phydev, RTL8211F_INSR);
/* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
return (err < 0) ? err : 0;
}
@@ -102,7 +102,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
reg = phy_read(phydev, 0x11);
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
@@ -114,7 +114,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
phy_write(phydev, 0x11, reg);
/* restore to default page 0 */
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
return 0;
}
From 3a2afedaf759bd28b2c94f4f1e9ef06909142728 Mon Sep 17 00:00:00 2001
From: Jassi Brar <jaswinder.singh@linaro.org>
Date: Tue, 12 Sep 2017 18:54:36 +0900
Subject: [PATCH] UPSTREAM: net: phy: realtek: add RTL8201F phy-id and
functions
Add RTL8201F phy-id and the related functions to the driver.
The original patch is as follows:
https://patchwork.kernel.org/patch/2538341/
Signed-off-by: Jongsung Kim <neidhard.kim@lge.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 513588dd44b09bb5fdd5066a4fbc1e7443b86d1c)
---
drivers/net/phy/realtek.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index d58cc8f518ac..422cf1f6a60c 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -29,10 +29,22 @@
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY 0x100
+#define RTL8201F_ISR 0x1e
+#define RTL8201F_IER 0x13
+
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
+static int rtl8201_ack_interrupt(struct phy_device *phydev)
+{
+ int err;
+
+ err = phy_read(phydev, RTL8201F_ISR);
+
+ return (err < 0) ? err : 0;
+}
+
static int rtl821x_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -54,6 +66,25 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
return (err < 0) ? err : 0;
}
+static int rtl8201_config_intr(struct phy_device *phydev)
+{
+ int err;
+
+ /* switch to page 7 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ err = phy_write(phydev, RTL8201F_IER,
+ BIT(13) | BIT(12) | BIT(11));
+ else
+ err = phy_write(phydev, RTL8201F_IER, 0);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return err;
+}
+
static int rtl8211b_config_intr(struct phy_device *phydev)
{
int err;
@@ -129,6 +160,18 @@ static struct phy_driver realtek_drvs[] = {
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.driver = { .owner = THIS_MODULE,},
+ }, {
+ .phy_id = 0x001cc816,
+ .name = "RTL8201F 10/100Mbps Ethernet",
+ .phy_id_mask = 0x001fffff,
+ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_aneg = &genphy_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &rtl8201_ack_interrupt,
+ .config_intr = &rtl8201_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
}, {
.phy_id = 0x001cc912,
.name = "RTL8211B Gigabit Ethernet",
@@ -186,6 +229,7 @@ static struct phy_driver realtek_drvs[] = {
module_phy_driver(realtek_drvs);
static struct mdio_device_id __maybe_unused realtek_tbl[] = {
+ { 0x001cc816, 0x001fffff },
{ 0x001cc912, 0x001fffff },
{ 0x001cc914, 0x001fffff },
{ 0x001cc915, 0x001fffff },
From 25fa2a3516b4836cc1ccf275dfb6f4eee1e21ba4 Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Sun, 12 Nov 2017 16:16:04 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix RTL8211F interrupt mode
After commit b94d22d94ad22 "ARM64: dts: meson-gx: add external PHY
interrupt on some platforms" ethernet stopped working on my Odroid-C2
which has a RTL8211F phy.
It turned out that no interrupts were triggered. Further analysis
showed the register INER can't be altered on page 0.
Because register INSR needs to be accessed via page 0xa43 I assumed
that register INER needs to be accessed via some page too.
Some brute force check resulted in page 0xa42 being the right one.
With this patch the phy is working properly in interrupt mode.
Fixes: 3447cf2e9a11 ("net/phy: Add support for Realtek RTL8211F")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Tested-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 3697d058b08d5b874f0253de173ef72e5d648f9a)
---
drivers/net/phy/realtek.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 422cf1f6a60c..a30d0c08c63b 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -115,11 +115,13 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
{
int err;
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
RTL8211F_INER_LINK_STATUS);
else
err = phy_write(phydev, RTL821x_INER, 0);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
return err;
}
From 4c621c2c47a298310290c3a053f5d5b920470927 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:24 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the BIT and GENMASK macros
This makes it easier to compare the #defines with the datasheets.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 8cc5baefbc0266b6d6c8e99cb8568f59be36a575)
---
drivers/net/phy/realtek.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index a30d0c08c63b..f8dc29a75828 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -13,21 +13,22 @@
* option) any later version.
*
*/
+#include <linux/bitops.h>
#include <linux/phy.h>
#include <linux/module.h>
#define RTL821x_PHYSR 0x11
-#define RTL821x_PHYSR_DUPLEX 0x2000
-#define RTL821x_PHYSR_SPEED 0xc000
+#define RTL821x_PHYSR_DUPLEX BIT(13)
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
#define RTL821x_INER 0x12
#define RTL821x_INER_INIT 0x6400
#define RTL821x_INSR 0x13
#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211E_INER_LINK_STATUS 0x400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS 0x0010
+#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY 0x100
+#define RTL8211F_TX_DELAY BIT(8)
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
From 3167d5ad9d83b77af30fe513bef24430bc31bdb4 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:25 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL821x_INER_INIT to
RTL8211B_INER_INIT
This macro is only used by the RTL8211B code. RTL8211E and RTL8211F both
use other bits to initialize the RTL821x_INER register.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 69021e32ec3ef02170482f6ed8130febaed27357)
---
drivers/net/phy/realtek.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f8dc29a75828..89308eac4088 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -21,7 +21,7 @@
#define RTL821x_PHYSR_DUPLEX BIT(13)
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
#define RTL821x_INER 0x12
-#define RTL821x_INER_INIT 0x6400
+#define RTL8211B_INER_INIT 0x6400
#define RTL821x_INSR 0x13
#define RTL821x_PAGE_SELECT 0x1f
#define RTL8211E_INER_LINK_STATUS BIT(10)
@@ -92,7 +92,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev)
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, RTL821x_INER,
- RTL821x_INER_INIT);
+ RTL8211B_INER_INIT);
else
err = phy_write(phydev, RTL821x_INER, 0);
From 351cf2d39cbbf73ca6369f2967176bc24b30dba0 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:26 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: group all register bit #defines
for RTL821x_INER
This simply moves all register bit #defines which describe the (PHY
specific) bits in the RTL821x_INER right below the RTL821x_INER register
definition. This makes it easier to spot which registers and bits belong
together.
No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit a82f266d240d87e6111878bbfe287024fb6857c1)
---
drivers/net/phy/realtek.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 89308eac4088..df97d903d2bf 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -20,13 +20,16 @@
#define RTL821x_PHYSR 0x11
#define RTL821x_PHYSR_DUPLEX BIT(13)
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
+
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211F_INER_LINK_STATUS BIT(4)
+
#define RTL821x_INSR 0x13
+
#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY BIT(8)
From 2eca64452d4ba8d77ee9edf9a554ec122b2fe53a Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:27 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the same indentation for all
#defines
This simply makes the code easier to read. No functional changes.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit f609ab0ed8e7bef2cd61d230bf9e83e1ec5b9ddb)
---
drivers/net/phy/realtek.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index df97d903d2bf..701f34ad7d8d 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -17,24 +17,25 @@
#include <linux/phy.h>
#include <linux/module.h>
-#define RTL821x_PHYSR 0x11
-#define RTL821x_PHYSR_DUPLEX BIT(13)
-#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
+#define RTL821x_PHYSR 0x11
+#define RTL821x_PHYSR_DUPLEX BIT(13)
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
-#define RTL821x_INER 0x12
-#define RTL8211B_INER_INIT 0x6400
-#define RTL8211E_INER_LINK_STATUS BIT(10)
-#define RTL8211F_INER_LINK_STATUS BIT(4)
+#define RTL821x_INER 0x12
+#define RTL8211B_INER_INIT 0x6400
+#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211F_INER_LINK_STATUS BIT(4)
-#define RTL821x_INSR 0x13
+#define RTL821x_INSR 0x13
-#define RTL821x_PAGE_SELECT 0x1f
+#define RTL821x_PAGE_SELECT 0x1f
-#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY BIT(8)
+#define RTL8211F_INSR 0x1d
-#define RTL8201F_ISR 0x1e
-#define RTL8201F_IER 0x13
+#define RTL8211F_TX_DELAY BIT(8)
+
+#define RTL8201F_ISR 0x1e
+#define RTL8201F_IER 0x13
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
From dedcf805b9b0cadc952d358a39ba5cfb7af7765e Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 22:51:28 +0100
Subject: [PATCH] UPSTREAM: net: phy: realtek: add utility functions to
read/write page addresses
Realtek PHYs implement the concept of so-called "extension pages". The
reason for this is probably because these PHYs expose more registers
than available in the standard address range.
After all read/write operations on such a page are done the driver
should switch back to page 0 where the standard MII registers (such as
MII_BMCR) are available.
When referring to such a register the datasheets of RTL8211E and
RTL8211F always specify:
- the page / "ext. page" which has to be written to RTL821x_PAGE_SELECT
- an address (sometimes also called reg)
These new utility functions make the existing code easier to read since
it removes some duplication (switching back to page 0 is done within the
new helpers for example).
No functional changes are intended.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 136819a6e8df374e6b9b424586ff11c9e241a1cb)
---
drivers/net/phy/realtek.c | 83 ++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 701f34ad7d8d..b1d52e61d91c 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -41,6 +41,39 @@ MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
+static int rtl8211x_page_read(struct phy_device *phydev, u16 page, u16 address)
+{
+ int ret;
+
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+ if (ret)
+ return ret;
+
+ ret = phy_read(phydev, address);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return ret;
+}
+
+static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
+ u16 address, u16 val)
+{
+ int ret;
+
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
+ if (ret)
+ return ret;
+
+ ret = phy_write(phydev, address, val);
+
+ /* restore to default page 0 */
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+
+ return ret;
+}
+
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -63,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
- err = phy_read(phydev, RTL8211F_INSR);
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+ err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR);
return (err < 0) ? err : 0;
}
static int rtl8201_config_intr(struct phy_device *phydev)
{
- int err;
-
- /* switch to page 7 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
+ u16 val;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
- err = phy_write(phydev, RTL8201F_IER,
- BIT(13) | BIT(12) | BIT(11));
+ val = BIT(13) | BIT(12) | BIT(11);
else
- err = phy_write(phydev, RTL8201F_IER, 0);
+ val = 0;
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
-
- return err;
+ return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val);
}
static int rtl8211b_config_intr(struct phy_device *phydev)
@@ -118,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
- int err;
+ u16 val;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
- err = phy_write(phydev, RTL821x_INER,
- RTL8211F_INER_LINK_STATUS);
+ val = RTL8211F_INER_LINK_STATUS;
else
- err = phy_write(phydev, RTL821x_INER, 0);
- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+ val = 0;
- return err;
+ return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
}
static int rtl8211f_config_init(struct phy_device *phydev)
{
int ret;
- u16 reg;
+ u16 val;
ret = genphy_config_init(phydev);
if (ret < 0)
return ret;
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
- reg = phy_read(phydev, 0x11);
+ ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
+ if (ret < 0)
+ return ret;
+
+ val = ret & 0xffff;
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
- reg |= RTL8211F_TX_DELAY;
+ val |= RTL8211F_TX_DELAY;
else
- reg &= ~RTL8211F_TX_DELAY;
+ val &= ~RTL8211F_TX_DELAY;
- phy_write(phydev, 0x11, reg);
- /* restore to default page 0 */
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
+ ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
+ if (ret)
+ return ret;
return 0;
}
From 9fece68d69e33eadcb03bb9dfd4240be21357603 Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:48 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: add support for configuring the
RX delay on RTL8211F
On RTL8211F the RX delay can also be enabled/disabled.
The overall behavior of the RX delay is similar to the behavior of the
TX delay, which was already supported by the driver.
The RX delay (similar to the TX delay) may be enabled using hardware pin
strapping. If the MAC already configures the RX delay (if required) then
the RX delay generated by the RTL8211F PHY has to be turned off.
While here, update the comment regarding the TX delay why it has to be
enabled or disabled within the driver.
Also avoid code-duplication by extracting the code to mask/unmask bits
in a paged register into a new rtl8211x_page_mask_bits helper function.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 55 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 45 insertions(+), 10 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index b1d52e61d91c..890ea9d18d27 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -32,7 +32,10 @@
#define RTL8211F_INSR 0x1d
-#define RTL8211F_TX_DELAY BIT(8)
+#define RTL8211F_RX_DELAY_REG 0x15
+#define RTL8211F_RX_DELAY_EN BIT(3)
+#define RTL8211F_TX_DELAY_REG 0x11
+#define RTL8211F_TX_DELAY_EN BIT(8)
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
@@ -74,6 +77,23 @@ static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
return ret;
}
+static int rtl8211x_page_mask_bits(struct phy_device *phydev, u16 page,
+ u16 address, u16 mask, u16 set)
+{
+ int ret;
+ u16 val;
+
+ ret = rtl8211x_page_read(phydev, page, address);
+ if (ret < 0)
+ return ret;
+
+ val = ret & 0xffff;
+ val &= ~mask;
+ val |= (set & mask);
+
+ return rtl8211x_page_write(phydev, page, address, val);
+}
+
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -160,20 +180,35 @@ static int rtl8211f_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
- ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
- if (ret < 0)
- return ret;
+ /*
+ * enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it.
+ * this is needed because it can be enabled by pin strapping and
+ * conflict with the TX-delay configured by the MAC.
+ */
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val = RTL8211F_TX_DELAY_EN;
+ else
+ val = 0;
- val = ret & 0xffff;
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_TX_DELAY_REG,
+ RTL8211F_TX_DELAY_EN, val);
+ if (ret)
+ return ret;
- /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+ /*
+ * enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it.
+ * this is needed because it can be enabled by pin strapping and
+ * conflict with the RX-delay configured by the MAC.
+ */
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
- val |= RTL8211F_TX_DELAY;
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val = RTL8211F_RX_DELAY_EN;
else
- val &= ~RTL8211F_TX_DELAY;
+ val = 0;
- ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_RX_DELAY_REG,
+ RTL8211F_RX_DELAY_EN, val);
if (ret)
return ret;
From 62c37a52b123444e2696963251428b0b9566721c Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:49 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: configure the INTB pin on
RTL8211F
The interrupt pin on the RTL8211F PHY can be used in two different
modes:
INTB
- the default mode of the PHY
- interrupts can be configured through page 0xa42 register RTL821x_INER
- interrupts can be ACK'ed through RTL8211F_INSR
- it acts as a level-interrupt which is active low
- Wake-on-LAN "wakeup" status is available in RTL8211F_INSR bit 7
PMEB:
- special mode for Wake-on-LAN
- interrupts configured through page 0xa42 register RTL821x_INER are
disabled
- it supports a "pulse low" waveform for the interrupt
For now we simply force the pin into INTB mode since the PHY driver does
not support Wake-on-LAN yet.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 890ea9d18d27..f307d220b49a 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -40,6 +40,9 @@
#define RTL8201F_ISR 0x1e
#define RTL8201F_IER 0x13
+#define RTL8211F_INTBCR 0x16
+#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
+
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
@@ -161,12 +164,32 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
+ int err;
u16 val;
- if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ /*
+ * The interrupt pin has two functions:
+ * 0: INTB: it acts as interrupt pin which can be configured
+ * through RTL821x_INER and the status can be read through
+ * RTL8211F_INSR
+ * 1: PMEB: a special "Power Management Event" mode for
+ * Wake-on-LAN operation (with support for a "pulse low"
+ * wave format). Interrupts configured through RTL821x_INER
+ * will not work in this mode
+ *
+ * select INTB mode in the "INTB pin control" register to
+ * ensure that the interrupt pin is in the correct mode.
+ */
+ err = rtl8211x_page_mask_bits(phydev, 0xd40, RTL8211F_INTBCR,
+ RTL8211F_INTBCR_INTB_PMEB, 0);
+ if (err)
+ return err;
+
val = RTL8211F_INER_LINK_STATUS;
- else
+ } else {
val = 0;
+ }
return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
}
From 4ea16aca3e2095f6904f1a534d8c668c383f595b Mon Sep 17 00:00:00 2001
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Sat, 2 Dec 2017 23:06:50 +0100
Subject: [PATCH] FROMLIST: net: phy: realtek: add more interrupt bits for
RTL8211E and RTL8211F
This documents a few more bits in the RTL821x_INER register for RTL8211E
and RTL8211F. These are added only to document them (as no public
datasheets are available for these PHYs), they are currently not used.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/phy/realtek.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f307d220b49a..15d342eefd6d 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -24,7 +24,14 @@
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211E_INER_ANEG_COMPLETED BIT(11)
+#define RTL8211E_INER_PAGE_RECEIVED BIT(12)
+#define RTL8211E_INER_ANEG_ERROR BIT(15)
#define RTL8211F_INER_LINK_STATUS BIT(4)
+#define RTL8211F_INER_PHY_REGISTER_ACCESSIBLE BIT(5)
+#define RTL8211F_INER_WOL_PME BIT(7)
+#define RTL8211F_INER_ALDPS_STATE_CHANGE BIT(9)
+#define RTL8211F_INER_JABBER BIT(10)
#define RTL821x_INSR 0x13

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,949 @@
From bbfc2a0527160401e8e668a0dbeb6fc7ad8ad625 Mon Sep 17 00:00:00 2001
From: Julia Lawall <Julia.Lawall@lip6.fr>
Date: Sat, 14 Nov 2015 18:05:20 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq: constify mmc_pwrseq_ops structures
The mmc_pwrseq_ops structures are never modified, so declare them as const.
Done with the help of Coccinelle.
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit ffedbd2210f2f4cba490a9205adc11fd1b89a852)
---
drivers/mmc/core/pwrseq.h | 2 +-
drivers/mmc/core/pwrseq_emmc.c | 2 +-
drivers/mmc/core/pwrseq_simple.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h
index 096da48c6a7e..133de0426687 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/drivers/mmc/core/pwrseq.h
@@ -16,7 +16,7 @@ struct mmc_pwrseq_ops {
};
struct mmc_pwrseq {
- struct mmc_pwrseq_ops *ops;
+ const struct mmc_pwrseq_ops *ops;
};
#ifdef CONFIG_OF
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index ad4f94ec7e8d..4a82bc77fe49 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -51,7 +51,7 @@ static void mmc_pwrseq_emmc_free(struct mmc_host *host)
kfree(pwrseq);
}
-static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
+static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
.post_power_on = mmc_pwrseq_emmc_reset,
.free = mmc_pwrseq_emmc_free,
};
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index d10538bb5e07..2b16263458af 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -87,7 +87,7 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
kfree(pwrseq);
}
-static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
+static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
.pre_power_on = mmc_pwrseq_simple_pre_power_on,
.post_power_on = mmc_pwrseq_simple_post_power_on,
.power_off = mmc_pwrseq_simple_power_off,
From 20acf1170bc2135cd600fceb97a18dcd7468fcfc Mon Sep 17 00:00:00 2001
From: Martin Fuzzey <mfuzzey@parkeon.com>
Date: Wed, 20 Jan 2016 16:08:03 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: Make reset-gpios optional to
match doc
The DT binding doc says reset-gpios is an optional property but the code
currently bails out if it is omitted.
This is a regression since it breaks previously working device trees.
Fix it by restoring the original documented behaviour.
Fixes: ce037275861e ("mmc: pwrseq_simple: use GPIO descriptors array API")
Tested-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 64a67d4762ce3ce4c9466eadd152d825fbf84967)
---
drivers/mmc/core/pwrseq_simple.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 2b16263458af..aba786daebca 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -29,15 +29,18 @@ struct mmc_pwrseq_simple {
static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
int value)
{
- int i;
struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
- int values[reset_gpios->ndescs];
- for (i = 0; i < reset_gpios->ndescs; i++)
- values[i] = value;
+ if (!IS_ERR(reset_gpios)) {
+ int i;
+ int values[reset_gpios->ndescs];
- gpiod_set_array_value_cansleep(reset_gpios->ndescs, reset_gpios->desc,
- values);
+ for (i = 0; i < reset_gpios->ndescs; i++)
+ values[i] = value;
+
+ gpiod_set_array_value_cansleep(
+ reset_gpios->ndescs, reset_gpios->desc, values);
+ }
}
static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
@@ -79,7 +82,8 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
struct mmc_pwrseq_simple, pwrseq);
- gpiod_put_array(pwrseq->reset_gpios);
+ if (!IS_ERR(pwrseq->reset_gpios))
+ gpiod_put_array(pwrseq->reset_gpios);
if (!IS_ERR(pwrseq->ext_clk))
clk_put(pwrseq->ext_clk);
@@ -112,7 +116,9 @@ struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
}
pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(pwrseq->reset_gpios)) {
+ if (IS_ERR(pwrseq->reset_gpios) &&
+ PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
+ PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
ret = PTR_ERR(pwrseq->reset_gpios);
goto clk_put;
}
From 6eab92ee9750e9e1f82f600ecfdd5e1990bb50e6 Mon Sep 17 00:00:00 2001
From: Peter Chen <peter.chen@freescale.com>
Date: Wed, 6 Jan 2016 11:34:10 +0800
Subject: [PATCH] UPSTREAM: mmc: core: pwrseq_simple: remove unused header file
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 62c03ca3ffa1ddf55a66411be02f7e4678771fce)
---
drivers/mmc/core/pwrseq_simple.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index aba786daebca..bc173e18b71c 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
-#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/mmc/host.h>
From 0eb034a2e78479467e7b0551f7b1ac3cfeec3c07 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:14 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: add to_pwrseq_simple() macro
This patch adds to_pwrseq_simple() macro to make the code more readable.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 5b96fea730ab79bdf6f8071cadf8208296bf5e8d)
---
drivers/mmc/core/pwrseq_simple.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index bc173e18b71c..f94271bb1f6b 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -25,6 +25,8 @@ struct mmc_pwrseq_simple {
struct gpio_descs *reset_gpios;
};
+#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq)
+
static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
int value)
{
@@ -44,8 +46,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) {
clk_prepare_enable(pwrseq->ext_clk);
@@ -57,16 +58,14 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
}
static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
@@ -78,8 +77,7 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
static void mmc_pwrseq_simple_free(struct mmc_host *host)
{
- struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_simple, pwrseq);
+ struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
if (!IS_ERR(pwrseq->reset_gpios))
gpiod_put_array(pwrseq->reset_gpios);
From adfbca02ae62674576d6d88a30ef9c1d8ec502fa Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:15 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq_emmc: add to_pwrseq_emmc() macro
This patch adds to_pwrseq_emmc() macro to make the code more readable.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit f01b72d0fd53b61cafd25b16d15e18b1ef8ae065)
---
drivers/mmc/core/pwrseq_emmc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index 4a82bc77fe49..c2d732aa464c 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -25,6 +25,8 @@ struct mmc_pwrseq_emmc {
struct gpio_desc *reset_gpio;
};
+#define to_pwrseq_emmc(p) container_of(p, struct mmc_pwrseq_emmc, pwrseq)
+
static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq)
{
gpiod_set_value(pwrseq->reset_gpio, 1);
@@ -35,16 +37,14 @@ static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq)
static void mmc_pwrseq_emmc_reset(struct mmc_host *host)
{
- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_emmc, pwrseq);
+ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
__mmc_pwrseq_emmc_reset(pwrseq);
}
static void mmc_pwrseq_emmc_free(struct mmc_host *host)
{
- struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq,
- struct mmc_pwrseq_emmc, pwrseq);
+ struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
unregister_restart_handler(&pwrseq->reset_nb);
gpiod_put(pwrseq->reset_gpio);
From 107ec2633bdbfb18f18b80ad2b9bd9c1a43fe3d8 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 14 Apr 2016 14:02:16 +0100
Subject: [PATCH] UPSTREAM: mmc: pwrseq: convert to proper platform device
simple-pwrseq and emmc-pwrseq drivers rely on platform_device
structure from of_find_device_by_node(), this works mostly. But, as there
is no driver associated with this devices, cases like default/init pinctrl
setup would never be performed by pwrseq. This becomes problem when the
gpios used in pwrseq require pinctrl setup.
Currently most of the common pinctrl setup is done in
drivers/base/pinctrl.c by pinctrl_bind_pins().
There are two ways to solve this issue on either convert pwrseq drivers
to a proper platform drivers or copy the exact code from
pcintrl_bind_pins(). I prefer converting pwrseq to proper drivers so that
other cases like setting up clks/parents from dt would also be possible.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit d97a1e5d7cd2b5b0edc02a40fe6897b710c9e10f)
---
drivers/mmc/core/Kconfig | 22 ++++++++
drivers/mmc/core/Makefile | 4 +-
drivers/mmc/core/pwrseq.c | 108 ++++++++++++++++++---------------------
drivers/mmc/core/pwrseq.h | 19 ++++---
drivers/mmc/core/pwrseq_emmc.c | 75 +++++++++++++++++----------
drivers/mmc/core/pwrseq_simple.c | 79 +++++++++++++++-------------
6 files changed, 178 insertions(+), 129 deletions(-)
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index 87cc07dedd9f..00dfaea06003 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -16,3 +16,25 @@ config MMC_PARANOID_SD_INIT
about re-trying SD init requests. This can be a useful
work-around for buggy controllers and hardware. Enable
if you are experiencing issues with SD detection.
+
+config PWRSEQ_EMMC
+ tristate "HW reset support for eMMC"
+ default y
+ depends on OF
+ help
+ This selects Hardware reset support aka pwrseq-emmc for eMMC
+ devices. By default this option is set to y.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwrseq_emmc.
+
+config PWRSEQ_SIMPLE
+ tristate "Simple HW reset support for MMC"
+ default y
+ depends on OF
+ help
+ This selects simple hardware reset support aka pwrseq-simple for MMC
+ devices. By default this option is set to y.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwrseq_simple.
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 2c25138f28b7..f007151dfdc6 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -8,5 +8,7 @@ mmc_core-y := core.o bus.o host.o \
sdio.o sdio_ops.o sdio_bus.o \
sdio_cis.o sdio_io.o sdio_irq.o \
quirks.o slot-gpio.o
-mmc_core-$(CONFIG_OF) += pwrseq.o pwrseq_simple.o pwrseq_emmc.o
+mmc_core-$(CONFIG_OF) += pwrseq.o
+obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o
+obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o
mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
index 4c1d1757dbf9..9386c4771814 100644
--- a/drivers/mmc/core/pwrseq.c
+++ b/drivers/mmc/core/pwrseq.c
@@ -8,88 +8,55 @@
* MMC power sequence management
*/
#include <linux/kernel.h>
-#include <linux/platform_device.h>
#include <linux/err.h>
+#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_platform.h>
#include <linux/mmc/host.h>
#include "pwrseq.h"
-struct mmc_pwrseq_match {
- const char *compatible;
- struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev);
-};
-
-static struct mmc_pwrseq_match pwrseq_match[] = {
- {
- .compatible = "mmc-pwrseq-simple",
- .alloc = mmc_pwrseq_simple_alloc,
- }, {
- .compatible = "mmc-pwrseq-emmc",
- .alloc = mmc_pwrseq_emmc_alloc,
- },
-};
-
-static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np)
-{
- struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) {
- if (of_device_is_compatible(np, pwrseq_match[i].compatible)) {
- match = &pwrseq_match[i];
- break;
- }
- }
-
- return match;
-}
+static DEFINE_MUTEX(pwrseq_list_mutex);
+static LIST_HEAD(pwrseq_list);
int mmc_pwrseq_alloc(struct mmc_host *host)
{
- struct platform_device *pdev;
struct device_node *np;
- struct mmc_pwrseq_match *match;
- struct mmc_pwrseq *pwrseq;
- int ret = 0;
+ struct mmc_pwrseq *p;
np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0);
if (!np)
return 0;
- pdev = of_find_device_by_node(np);
- if (!pdev) {
- ret = -ENODEV;
- goto err;
- }
+ mutex_lock(&pwrseq_list_mutex);
+ list_for_each_entry(p, &pwrseq_list, pwrseq_node) {
+ if (p->dev->of_node == np) {
+ if (!try_module_get(p->owner))
+ dev_err(host->parent,
+ "increasing module refcount failed\n");
+ else
+ host->pwrseq = p;
- match = mmc_pwrseq_find(np);
- if (IS_ERR(match)) {
- ret = PTR_ERR(match);
- goto err;
+ break;
+ }
}
- pwrseq = match->alloc(host, &pdev->dev);
- if (IS_ERR(pwrseq)) {
- ret = PTR_ERR(pwrseq);
- goto err;
- }
+ of_node_put(np);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ if (!host->pwrseq)
+ return -EPROBE_DEFER;
- host->pwrseq = pwrseq;
dev_info(host->parent, "allocated mmc-pwrseq\n");
-err:
- of_node_put(np);
- return ret;
+ return 0;
}
void mmc_pwrseq_pre_power_on(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->pre_power_on)
+ if (pwrseq && pwrseq->ops->pre_power_on)
pwrseq->ops->pre_power_on(host);
}
@@ -97,7 +64,7 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->post_power_on)
+ if (pwrseq && pwrseq->ops->post_power_on)
pwrseq->ops->post_power_on(host);
}
@@ -105,7 +72,7 @@ void mmc_pwrseq_power_off(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->power_off)
+ if (pwrseq && pwrseq->ops->power_off)
pwrseq->ops->power_off(host);
}
@@ -113,8 +80,31 @@ void mmc_pwrseq_free(struct mmc_host *host)
{
struct mmc_pwrseq *pwrseq = host->pwrseq;
- if (pwrseq && pwrseq->ops && pwrseq->ops->free)
- pwrseq->ops->free(host);
+ if (pwrseq) {
+ module_put(pwrseq->owner);
+ host->pwrseq = NULL;
+ }
+}
+
+int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
+{
+ if (!pwrseq || !pwrseq->ops || !pwrseq->dev)
+ return -EINVAL;
- host->pwrseq = NULL;
+ mutex_lock(&pwrseq_list_mutex);
+ list_add(&pwrseq->pwrseq_node, &pwrseq_list);
+ mutex_unlock(&pwrseq_list_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_register);
+
+void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq)
+{
+ if (pwrseq) {
+ mutex_lock(&pwrseq_list_mutex);
+ list_del(&pwrseq->pwrseq_node);
+ mutex_unlock(&pwrseq_list_mutex);
+ }
}
+EXPORT_SYMBOL_GPL(mmc_pwrseq_unregister);
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h
index 133de0426687..d69e751f148b 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/drivers/mmc/core/pwrseq.h
@@ -8,32 +8,39 @@
#ifndef _MMC_CORE_PWRSEQ_H
#define _MMC_CORE_PWRSEQ_H
+#include <linux/mmc/host.h>
+
struct mmc_pwrseq_ops {
void (*pre_power_on)(struct mmc_host *host);
void (*post_power_on)(struct mmc_host *host);
void (*power_off)(struct mmc_host *host);
- void (*free)(struct mmc_host *host);
};
struct mmc_pwrseq {
const struct mmc_pwrseq_ops *ops;
+ struct device *dev;
+ struct list_head pwrseq_node;
+ struct module *owner;
};
#ifdef CONFIG_OF
+int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq);
+void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq);
+
int mmc_pwrseq_alloc(struct mmc_host *host);
void mmc_pwrseq_pre_power_on(struct mmc_host *host);
void mmc_pwrseq_post_power_on(struct mmc_host *host);
void mmc_pwrseq_power_off(struct mmc_host *host);
void mmc_pwrseq_free(struct mmc_host *host);
-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
- struct device *dev);
-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
- struct device *dev);
-
#else
+static inline int mmc_pwrseq_register(struct mmc_pwrseq *pwrseq)
+{
+ return -ENOSYS;
+}
+static inline void mmc_pwrseq_unregister(struct mmc_pwrseq *pwrseq) {}
static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; }
static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {}
static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {}
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index c2d732aa464c..adc9c0c614fb 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -9,6 +9,9 @@
*/
#include <linux/delay.h>
#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -42,20 +45,6 @@ static void mmc_pwrseq_emmc_reset(struct mmc_host *host)
__mmc_pwrseq_emmc_reset(pwrseq);
}
-static void mmc_pwrseq_emmc_free(struct mmc_host *host)
-{
- struct mmc_pwrseq_emmc *pwrseq = to_pwrseq_emmc(host->pwrseq);
-
- unregister_restart_handler(&pwrseq->reset_nb);
- gpiod_put(pwrseq->reset_gpio);
- kfree(pwrseq);
-}
-
-static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
- .post_power_on = mmc_pwrseq_emmc_reset,
- .free = mmc_pwrseq_emmc_free,
-};
-
static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
unsigned long mode, void *cmd)
{
@@ -66,21 +55,22 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
return NOTIFY_DONE;
}
-struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
- struct device *dev)
+static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
+ .post_power_on = mmc_pwrseq_emmc_reset,
+};
+
+static int mmc_pwrseq_emmc_probe(struct platform_device *pdev)
{
struct mmc_pwrseq_emmc *pwrseq;
- int ret = 0;
+ struct device *dev = &pdev->dev;
- pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL);
+ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
if (!pwrseq)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
- pwrseq->reset_gpio = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
- if (IS_ERR(pwrseq->reset_gpio)) {
- ret = PTR_ERR(pwrseq->reset_gpio);
- goto free;
- }
+ pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(pwrseq->reset_gpio))
+ return PTR_ERR(pwrseq->reset_gpio);
/*
* register reset handler to ensure emmc reset also from
@@ -92,9 +82,38 @@ struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
register_restart_handler(&pwrseq->reset_nb);
pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops;
+ pwrseq->pwrseq.dev = dev;
+ pwrseq->pwrseq.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, pwrseq);
+
+ return mmc_pwrseq_register(&pwrseq->pwrseq);
+}
+
+static int mmc_pwrseq_emmc_remove(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_emmc *pwrseq = platform_get_drvdata(pdev);
+
+ unregister_restart_handler(&pwrseq->reset_nb);
+ mmc_pwrseq_unregister(&pwrseq->pwrseq);
- return &pwrseq->pwrseq;
-free:
- kfree(pwrseq);
- return ERR_PTR(ret);
+ return 0;
}
+
+static const struct of_device_id mmc_pwrseq_emmc_of_match[] = {
+ { .compatible = "mmc-pwrseq-emmc",},
+ {/* sentinel */},
+};
+
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_emmc_of_match);
+
+static struct platform_driver mmc_pwrseq_emmc_driver = {
+ .probe = mmc_pwrseq_emmc_probe,
+ .remove = mmc_pwrseq_emmc_remove,
+ .driver = {
+ .name = "pwrseq_emmc",
+ .of_match_table = mmc_pwrseq_emmc_of_match,
+ },
+};
+
+module_platform_driver(mmc_pwrseq_emmc_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index f94271bb1f6b..450d907c6e6c 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -8,7 +8,10 @@
* Simple MMC power sequence management
*/
#include <linux/clk.h>
+#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -75,58 +78,64 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
}
}
-static void mmc_pwrseq_simple_free(struct mmc_host *host)
-{
- struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
-
- if (!IS_ERR(pwrseq->reset_gpios))
- gpiod_put_array(pwrseq->reset_gpios);
-
- if (!IS_ERR(pwrseq->ext_clk))
- clk_put(pwrseq->ext_clk);
-
- kfree(pwrseq);
-}
-
static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
.pre_power_on = mmc_pwrseq_simple_pre_power_on,
.post_power_on = mmc_pwrseq_simple_post_power_on,
.power_off = mmc_pwrseq_simple_power_off,
- .free = mmc_pwrseq_simple_free,
};
-struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
- struct device *dev)
+static const struct of_device_id mmc_pwrseq_simple_of_match[] = {
+ { .compatible = "mmc-pwrseq-simple",},
+ {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_simple_of_match);
+
+static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
{
struct mmc_pwrseq_simple *pwrseq;
- int ret = 0;
+ struct device *dev = &pdev->dev;
- pwrseq = kzalloc(sizeof(*pwrseq), GFP_KERNEL);
+ pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
if (!pwrseq)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
- pwrseq->ext_clk = clk_get(dev, "ext_clock");
- if (IS_ERR(pwrseq->ext_clk) &&
- PTR_ERR(pwrseq->ext_clk) != -ENOENT) {
- ret = PTR_ERR(pwrseq->ext_clk);
- goto free;
- }
+ pwrseq->ext_clk = devm_clk_get(dev, "ext_clock");
+ if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT)
+ return PTR_ERR(pwrseq->ext_clk);
- pwrseq->reset_gpios = gpiod_get_array(dev, "reset", GPIOD_OUT_HIGH);
+ pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset",
+ GPIOD_OUT_HIGH);
if (IS_ERR(pwrseq->reset_gpios) &&
PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
- ret = PTR_ERR(pwrseq->reset_gpios);
- goto clk_put;
+ return PTR_ERR(pwrseq->reset_gpios);
}
+ pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
+ pwrseq->pwrseq.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, pwrseq);
- return &pwrseq->pwrseq;
-clk_put:
- if (!IS_ERR(pwrseq->ext_clk))
- clk_put(pwrseq->ext_clk);
-free:
- kfree(pwrseq);
- return ERR_PTR(ret);
+ return mmc_pwrseq_register(&pwrseq->pwrseq);
}
+
+static int mmc_pwrseq_simple_remove(struct platform_device *pdev)
+{
+ struct mmc_pwrseq_simple *pwrseq = platform_get_drvdata(pdev);
+
+ mmc_pwrseq_unregister(&pwrseq->pwrseq);
+
+ return 0;
+}
+
+static struct platform_driver mmc_pwrseq_simple_driver = {
+ .probe = mmc_pwrseq_simple_probe,
+ .remove = mmc_pwrseq_simple_remove,
+ .driver = {
+ .name = "pwrseq_simple",
+ .of_match_table = mmc_pwrseq_simple_of_match,
+ },
+};
+
+module_platform_driver(mmc_pwrseq_simple_driver);
+MODULE_LICENSE("GPL v2");
From d4986d574cca4ea8985a3d725ff4190b8ad584f3 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 7 Aug 2016 21:02:38 +0200
Subject: [PATCH] UPSTREAM: mmc: pwrseq-simple: Add an optional
post-power-on-delay
Some devices need a while to boot their firmware after providing clks /
de-asserting resets before they are ready to receive sdio commands.
This commits adds a post-power-on-delay-ms devicetree property to
mmc-pwrseq-simple for use with such devices.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
(cherry picked from commit 721e0497172f0fa661eed2d63367cddf479f35e8)
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 9 +++++++++
2 files changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index ce0e76749671..e25436861867 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -16,6 +16,8 @@ Optional properties:
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entry:
"ext_clock" (External clock provided to the card).
+- post-power-on-delay-ms : Delay in ms after powering the card and
+ de-asserting the reset-gpios (if any)
Example:
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 450d907c6e6c..1304160de168 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -16,6 +16,8 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
+#include <linux/delay.h>
+#include <linux/property.h>
#include <linux/mmc/host.h>
@@ -24,6 +26,7 @@
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
+ u32 post_power_on_delay_ms;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
};
@@ -64,6 +67,9 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
+
+ if (pwrseq->post_power_on_delay_ms)
+ msleep(pwrseq->post_power_on_delay_ms);
}
static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
@@ -111,6 +117,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
return PTR_ERR(pwrseq->reset_gpios);
}
+ device_property_read_u32(dev, "post-power-on-delay-ms",
+ &pwrseq->post_power_on_delay_ms);
+
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
pwrseq->pwrseq.owner = THIS_MODULE;
From dc809aa3772b2cbc912b34bf6a99daba7c071cac Mon Sep 17 00:00:00 2001
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Sat, 6 May 2017 11:41:30 +0200
Subject: [PATCH] UPSTREAM: mmc: dt: pwrseq-simple: Invent power-off-delay-us
During power off, after the GPIO pin has been asserted, some devices like
the Wifi chip from TI, Wl18xx, needs a delay before the host continues with
clock gating and turning off regulators as to follow a graceful shutdown
sequence.
Therefore invent an optional power-off-delay-us DT binding for
mmc-pwrseq-simple, to allow us to support this constraint.
Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: linux-mmc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index e25436861867..9029b45b8a22 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -18,6 +18,8 @@ Optional properties:
"ext_clock" (External clock provided to the card).
- post-power-on-delay-ms : Delay in ms after powering the card and
de-asserting the reset-gpios (if any)
+- power-off-delay-us : Delay in us after asserting the reset-gpios (if any)
+ during power off of the card.
Example:
From e0841b21b5b9597b674ddbf3f62fe0c418467a93 Mon Sep 17 00:00:00 2001
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Sat, 6 May 2017 11:43:05 +0200
Subject: [PATCH] UPSTREAM: mmc: pwrseq_simple: Parse DTS for the
power-off-delay-us property
If the optional power-off-delay-us property is found, insert the
corresponding delay after asserting the GPIO during power off. This enables
a graceful shutdown sequence for some devices.
Cc: linux-mmc@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
(cherry picked from commit e9256e142f597edf90c68cec22db4c4aebaa27de)
---
drivers/mmc/core/pwrseq_simple.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 1304160de168..13ef162cf066 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -27,6 +27,7 @@ struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
u32 post_power_on_delay_ms;
+ u32 power_off_delay_us;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
};
@@ -78,6 +79,10 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+ if (pwrseq->power_off_delay_us)
+ usleep_range(pwrseq->power_off_delay_us,
+ 2 * pwrseq->power_off_delay_us);
+
if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) {
clk_disable_unprepare(pwrseq->ext_clk);
pwrseq->clk_enabled = false;
@@ -119,6 +124,8 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
device_property_read_u32(dev, "post-power-on-delay-ms",
&pwrseq->post_power_on_delay_ms);
+ device_property_read_u32(dev, "power-off-delay-us",
+ &pwrseq->power_off_delay_us);
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;

View File

@ -1,8 +1,140 @@
From c5762affa4dc61b624b0440a4b4846550a305552 Mon Sep 17 00:00:00 2001
From b9995f420ecbdc8496a3f92f4e35173268fc2697 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 4 Feb 2018 10:47:28 +0100
Subject: [PATCH] Revert "dmaengine: pl330: fix bug that chan descdone is null"
This reverts commit 636c30b38ae6ec499735ce7621ba474944b4e9b7.
---
drivers/dma/pl330.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 08179f5d0428..766ab72d119e 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1785,17 +1785,16 @@ static int pl330_update(struct pl330_dmac *pl330)
/* Detach the req */
descdone = thrd->req[active].desc;
- if (descdone) {
- if (!descdone->cyclic) {
- thrd->req[active].desc = NULL;
- thrd->req_running = -1;
- /* Get going again ASAP */
- _start(thrd);
- }
- /* For now, just make a list of callbacks to be done */
- list_add_tail(&descdone->rqd, &pl330->req_done);
+ if (!descdone->cyclic) {
+ thrd->req[active].desc = NULL;
+ thrd->req_running = -1;
+ /* Get going again ASAP */
+ _start(thrd);
}
+
+ /* For now, just make a list of callbacks to be done */
+ list_add_tail(&descdone->rqd, &pl330->req_done);
}
}
From 4c25aa573e13f31f628d10ae41f24264fe15695c Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 4 Feb 2018 10:47:38 +0100
Subject: [PATCH] Revert "dmaengine: pl330: flush before first loop"
This reverts commit 34be2cf4679cadbf910de9651d54b46930166446.
---
drivers/dma/pl330.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 766ab72d119e..055e3cd8832c 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1347,11 +1347,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run,
/* forever loop */
off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);
off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
- off += _emit_FLUSHP(dry_run, &buf[off],
- pxs->desc->peri);
-#endif
+
/* loop0 */
off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
ljmp0 = off;
@@ -1427,11 +1423,7 @@ static inline int _setup_loops(struct pl330_dmac *pl330,
u32 ccr = pxs->ccr;
unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
int off = 0;
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
- off += _emit_FLUSHP(dry_run, &buf[off],
- pxs->desc->peri);
-#endif
+
while (bursts) {
c = bursts;
off += _loop(pl330, dry_run, &buf[off], &c, pxs);
From 4977bdedb837ac640fd6be482ed7c501959e4a55 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 4 Feb 2018 10:47:51 +0100
Subject: [PATCH] Revert "dmaengine: pl330: fix 2 bursts transfer when dma
flushes"
This reverts commit 98753e172dc1d06cf4d61c48f5c3487df0247472.
---
drivers/dma/pl330.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 055e3cd8832c..ce52aa411c0b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1169,16 +1169,6 @@ static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
off += _emit_ST(dry_run, &buf[off], ALWAYS);
-#ifdef CONFIG_ARCH_ROCKCHIP
- /*
- * Make suree dma has finish transmission, or later flush may
- * cause dma second transmission,and fifo is overrun.
- */
- off += _emit_WMB(dry_run, &buf[off]);
- off += _emit_NOP(dry_run, &buf[off]);
- off += _emit_WMB(dry_run, &buf[off]);
- off += _emit_NOP(dry_run, &buf[off]);
-#endif
if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
off += _emit_FLUSHP(dry_run, &buf[off],
@@ -1199,16 +1189,6 @@ static inline int _ldst_memtodev(struct pl330_dmac *pl330,
off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
off += _emit_LD(dry_run, &buf[off], ALWAYS);
off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-#ifdef CONFIG_ARCH_ROCKCHIP
- /*
- * Make suree dma has finish transmission, or later flush may
- * cause dma second transmission,and fifo is overrun.
- */
- off += _emit_WMB(dry_run, &buf[off]);
- off += _emit_NOP(dry_run, &buf[off]);
- off += _emit_WMB(dry_run, &buf[off]);
- off += _emit_NOP(dry_run, &buf[off]);
-#endif
if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
off += _emit_FLUSHP(dry_run, &buf[off],
From 29be0d6a2e7bace45bc18728b59d7bcac498cb0c Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sat, 21 Oct 2017 19:49:27 +0200
Subject: [PATCH 01/16] Revert "dmaengine: pl330: _loop_cyclic fix cycles of
last loop"
Subject: [PATCH] Revert "dmaengine: pl330: _loop_cyclic fix cycles of last
loop"
This reverts commit d7155171cbc65e45b5b0c8db03fd16fa57a181f2.
---
@ -10,7 +142,7 @@ This reverts commit d7155171cbc65e45b5b0c8db03fd16fa57a181f2.
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index cd05495735d7..1e5c79b20c5b 100644
index ce52aa411c0b..9fbd8d863774 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1366,7 +1366,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run,
@ -23,11 +155,36 @@ index cd05495735d7..1e5c79b20c5b 100644
off += _bursts(pl330, dry_run, &buf[off], pxs, 1);
lpend.cond = ALWAYS;
From 7d241ca0d9e3c658f92c54614cf50812557fb899 Mon Sep 17 00:00:00 2001
From 350bb8b0d3efbeb398c058d6343a7a9466230b36 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Sun, 4 Feb 2018 11:05:44 +0100
Subject: [PATCH] Revert "dmaengine: pl330: pl330_tasklet init power_down by
pch->active"
This reverts commit 796b13f24a158f14d540bcf7316d843f72242c0d.
---
drivers/dma/pl330.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9fbd8d863774..359475bbe89f 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2163,7 +2163,7 @@ static void pl330_tasklet(unsigned long data)
spin_lock(&pch->thread->dmac->lock);
_stop(pch->thread);
spin_unlock(&pch->thread->dmac->lock);
- power_down = pch->active;
+ power_down = true;
pch->active = false;
} else {
/* Make sure the PL330 Channel thread is active */
From 3eff212db53fd374baa1a9040212442057bb9110 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 16 Jun 2017 23:14:54 +0200
Subject: [PATCH 02/16] Revert "dmaengine: pl330: _loop_cyclic supports
unaligned size"
Subject: [PATCH] Revert "dmaengine: pl330: _loop_cyclic supports unaligned
size"
This reverts commit 13dbe2cccd5851540af8158b12499c33801b6ef6.
---
@ -35,7 +192,7 @@ This reverts commit 13dbe2cccd5851540af8158b12499c33801b6ef6.
1 file changed, 10 insertions(+), 28 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 1e5c79b20c5b..4661dfb1a195 100644
index 359475bbe89f..3fa6a7e474de 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1356,28 +1356,6 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run,
@ -99,10 +256,10 @@ index 1e5c79b20c5b..4661dfb1a195 100644
pxs, thrd->ev);
}
From a21f49560bf8cf38b5832a0f37d4c16610bec2df Mon Sep 17 00:00:00 2001
From 7835c891fdb8016da760f81b95291333b03c9fbc Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 16 Jun 2017 23:14:54 +0200
Subject: [PATCH 03/16] Revert "dmaengine: pl330: redefine the cyclic transfer"
Subject: [PATCH] Revert "dmaengine: pl330: redefine the cyclic transfer"
This reverts commit 5f638786e66089344c9cf594b81fbf02cd794f15.
---
@ -110,7 +267,7 @@ This reverts commit 5f638786e66089344c9cf594b81fbf02cd794f15.
1 file changed, 29 insertions(+), 108 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 4661dfb1a195..d8912a4216df 100644
index 3fa6a7e474de..0452a189d7fd 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1303,76 +1303,6 @@ static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
@ -291,7 +448,7 @@ index 4661dfb1a195..d8912a4216df 100644
}
return off;
@@ -2656,7 +2583,6 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
@@ -2649,7 +2576,6 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
{
struct dma_pl330_desc *desc = NULL;
struct dma_pl330_chan *pch = to_pchan(chan);
@ -299,7 +456,7 @@ index 4661dfb1a195..d8912a4216df 100644
dma_addr_t dst;
dma_addr_t src;
@@ -2695,12 +2621,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
@@ -2688,12 +2614,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
desc->rqtype = direction;
desc->rqcfg.brst_size = pch->burst_sz;
@ -314,10 +471,10 @@ index 4661dfb1a195..d8912a4216df 100644
fill_px(&desc->px, dst, src, period_len);
From 7cd3fa397393d461d94167554653ef168b8e703d Mon Sep 17 00:00:00 2001
From e5c15e6005f796dae98de9e7a0d844bd101cd974 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 16 Jun 2017 23:14:54 +0200
Subject: [PATCH 04/16] Revert "dmaengine: pl330: make transfer run infinitely
Subject: [PATCH] Revert "dmaengine: pl330: make transfer run infinitely
without CPU intervention"
This reverts commit e8a6e5086cb82d59cae6ae029b1eb4432cc62288.
@ -326,7 +483,7 @@ This reverts commit e8a6e5086cb82d59cae6ae029b1eb4432cc62288.
1 file changed, 105 insertions(+), 94 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index d8912a4216df..58e99ae039f8 100644
index 0452a189d7fd..47c2e67f0296 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -447,6 +447,9 @@ struct dma_pl330_chan {
@ -440,7 +597,7 @@ index d8912a4216df..58e99ae039f8 100644
/* For now, just make a list of callbacks to be done */
list_add_tail(&descdone->rqd, &pl330->req_done);
@@ -2051,27 +2028,12 @@ static void pl330_tasklet(unsigned long data)
@@ -2043,27 +2020,12 @@ static void pl330_tasklet(unsigned long data)
spin_lock_irqsave(&pch->lock, flags);
/* Pick up ripe tomatoes */
@ -471,7 +628,7 @@ index d8912a4216df..58e99ae039f8 100644
/* Try to submit a req imm. next to the last completed cookie */
fill_queue(pch);
@@ -2099,8 +2061,20 @@ static void pl330_tasklet(unsigned long data)
@@ -2091,8 +2053,20 @@ static void pl330_tasklet(unsigned long data)
callback = desc->txd.callback;
callback_param = desc->txd.callback_param;
@ -494,15 +651,15 @@ index d8912a4216df..58e99ae039f8 100644
dma_descriptor_unmap(&desc->txd);
@@ -2160,6 +2134,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
spin_lock_irqsave(&pch->lock, flags);
@@ -2152,6 +2126,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
spin_lock_irqsave(&pl330->lock, flags);
dma_cookie_init(chan);
+ pch->cyclic = false;
pch->thread = pl330_request_channel(pl330);
if (!pch->thread) {
@@ -2282,7 +2257,8 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
@@ -2275,7 +2250,8 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
pl330_release_channel(pch->thread);
pch->thread = NULL;
@ -510,9 +667,9 @@ index d8912a4216df..58e99ae039f8 100644
+ if (pch->cyclic)
+ list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
spin_unlock_irqrestore(&pch->lock, flags);
spin_unlock_irqrestore(&pl330->lock, flags);
pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
@@ -2336,7 +2312,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2329,7 +2305,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
/* Check in pending list */
list_for_each_entry(desc, &pch->work_list, node) {
@ -521,7 +678,7 @@ index d8912a4216df..58e99ae039f8 100644
transferred = desc->bytes_requested;
else if (running && desc == running)
transferred =
@@ -2408,8 +2384,12 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
@@ -2401,8 +2377,12 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
/* Assign cookies to all nodes */
while (!list_empty(&last->node)) {
desc = list_entry(last->node.next, struct dma_pl330_desc, node);
@ -535,7 +692,7 @@ index d8912a4216df..58e99ae039f8 100644
dma_cookie_assign(&desc->txd);
list_move_tail(&desc->node, &pch->submitted_list);
@@ -2509,9 +2489,6 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
@@ -2502,9 +2482,6 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
desc->peri = peri_id ? pch->chan.chan_id : 0;
desc->rqcfg.pcfg = &pch->dmac->pcfg;
@ -545,7 +702,7 @@ index d8912a4216df..58e99ae039f8 100644
dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
return desc;
@@ -2581,8 +2558,10 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
@@ -2574,8 +2551,10 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags)
{
@ -557,7 +714,7 @@ index d8912a4216df..58e99ae039f8 100644
dma_addr_t dst;
dma_addr_t src;
@@ -2595,38 +2574,70 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
@@ -2588,38 +2567,70 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
return NULL;
}
@ -657,11 +814,11 @@ index d8912a4216df..58e99ae039f8 100644
return &desc->txd;
From 5e0a2880602942d120459525a752e86533300c44 Mon Sep 17 00:00:00 2001
From 6fa8512feac35cc27a6b929a0a9b5baaf8ec104d Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 16 Jun 2017 23:14:55 +0200
Subject: [PATCH 05/16] Revert "dmaengine: pl330: support transfer that doesn't
align with (burst len * burst size)"
Subject: [PATCH] Revert "dmaengine: pl330: support transfer that doesn't align
with (burst len * burst size)"
This reverts commit c66ecf19b98ffac86177c29859e683de39f44e73.
---
@ -669,7 +826,7 @@ This reverts commit c66ecf19b98ffac86177c29859e683de39f44e73.
1 file changed, 3 insertions(+), 20 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 58e99ae039f8..f4837f5b4e87 100644
index 47c2e67f0296..b5cf3fe9e9c3 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -240,7 +240,6 @@ enum pl330_byteswap {
@ -717,11 +874,11 @@ index 58e99ae039f8..f4837f5b4e87 100644
off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
From fd77628162b4a13bc54a9187dc25fbc65ad79f37 Mon Sep 17 00:00:00 2001
From 0e2fc7209d34d86502cfe4cf2a8808dc51e99492 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Fri, 16 Jun 2017 23:14:55 +0200
Subject: [PATCH 06/16] Revert "dmaengine: pl330: add burst mode according to
dts config"
Subject: [PATCH] Revert "dmaengine: pl330: add burst mode according to dts
config"
This reverts commit 8e770f371cc27f8828cb9ceb0516adc23fe75995.
---
@ -729,7 +886,7 @@ This reverts commit 8e770f371cc27f8828cb9ceb0516adc23fe75995.
1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index f4837f5b4e87..778be86e908c 100644
index b5cf3fe9e9c3..131763534a39 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -494,8 +494,6 @@ struct pl330_dmac {
@ -769,7 +926,7 @@ index f4837f5b4e87..778be86e908c 100644
while (cyc--) {
off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
@@ -2600,12 +2608,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
@@ -2593,12 +2601,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
desc->rqtype = direction;
desc->rqcfg.brst_size = pch->burst_sz;
@ -783,7 +940,7 @@ index f4837f5b4e87..778be86e908c 100644
desc->bytes_requested = period_len;
fill_px(&desc->px, dst, src, period_len);
@@ -2707,7 +2710,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
@@ -2700,7 +2703,6 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
{
struct dma_pl330_desc *first, *desc = NULL;
struct dma_pl330_chan *pch = to_pchan(chan);
@ -791,7 +948,7 @@ index f4837f5b4e87..778be86e908c 100644
struct scatterlist *sg;
int i;
dma_addr_t addr;
@@ -2751,12 +2753,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
@@ -2744,12 +2746,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
}
desc->rqcfg.brst_size = pch->burst_sz;
@ -805,7 +962,7 @@ index f4837f5b4e87..778be86e908c 100644
desc->rqtype = direction;
desc->bytes_requested = sg_dma_len(sg);
}
@@ -2852,11 +2849,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
@@ -2845,11 +2842,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
@ -818,10 +975,10 @@ index f4837f5b4e87..778be86e908c 100644
for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
if (of_property_read_bool(np, of_quirks[i].quirk))
From 754e41a208e456b127896f0c017ca523d7e93ccc Mon Sep 17 00:00:00 2001
From 11bc7b36d8a54c6c1858c23a1e91a660ab8f34c8 Mon Sep 17 00:00:00 2001
From: Vinod Koul <vinod.koul@intel.com>
Date: Tue, 5 Jul 2016 10:02:16 +0530
Subject: [PATCH 07/16] UPSTREAM: dmaengine: pl330: explicitly freeup irq
Subject: [PATCH] UPSTREAM: dmaengine: pl330: explicitly freeup irq
dmaengine device should explicitly call devm_free_irq() when using
devm_request_irq().
@ -838,10 +995,10 @@ Cc: Linus Walleij <linus.walleij@linaro.org>
1 file changed, 6 insertions(+)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 778be86e908c..4e6590f90994 100644
index 131763534a39..5b4a419673fc 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -3016,12 +3016,18 @@ static int pl330_remove(struct amba_device *adev)
@@ -3009,12 +3009,18 @@ static int pl330_remove(struct amba_device *adev)
{
struct pl330_dmac *pl330 = amba_get_drvdata(adev);
struct dma_pl330_chan *pch, *_p;
@ -861,11 +1018,11 @@ index 778be86e908c..4e6590f90994 100644
/* Idle the DMAC */
From d486322e47fdaaf0ba14c5dc1a3bad97400814b0 Mon Sep 17 00:00:00 2001
From 0406b9fd94d38cc2de78e82bd7b7c3272991e7d5 Mon Sep 17 00:00:00 2001
From: Stephen Barber <smbarber@chromium.org>
Date: Thu, 18 Aug 2016 17:59:59 -0700
Subject: [PATCH 08/16] UPSTREAM: dmaengine: pl330: fix residual for
non-running BUSY descriptors
Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix residual for non-running BUSY
descriptors
Only one descriptor in the work list should be running at
any given time, but it's possible to have an enqueued BUSY
@ -883,10 +1040,10 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 4e6590f90994..16f578f1d050 100644
index 5b4a419673fc..aab5abab5a10 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2284,7 +2284,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2277,7 +2277,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
{
enum dma_status ret;
unsigned long flags;
@ -895,7 +1052,7 @@ index 4e6590f90994..16f578f1d050 100644
struct dma_pl330_chan *pch = to_pchan(chan);
unsigned int transferred, residual = 0;
@@ -2301,6 +2301,8 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2294,6 +2294,8 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
if (pch->thread->req_running != -1)
running = pch->thread->req[pch->thread->req_running].desc;
@ -904,7 +1061,7 @@ index 4e6590f90994..16f578f1d050 100644
/* Check in pending list */
list_for_each_entry(desc, &pch->work_list, node) {
if (desc->status == DONE)
@@ -2308,6 +2310,15 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2301,6 +2303,15 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
else if (running && desc == running)
transferred =
pl330_get_current_xferred_count(pch, desc);
@ -921,10 +1078,10 @@ index 4e6590f90994..16f578f1d050 100644
transferred = 0;
residual += desc->bytes_requested - transferred;
From be63b825e6305654e11be4313e083fbafc09825c Mon Sep 17 00:00:00 2001
From 9bda78186df672f7c813dfd7db3bcd6d557e11e5 Mon Sep 17 00:00:00 2001
From: Hsin-Yu Chao <hychao@chromium.org>
Date: Tue, 23 Aug 2016 17:16:55 +0800
Subject: [PATCH 09/16] UPSTREAM: dmaengine: pl330: Acquire dmac's spinlock in
Subject: [PATCH] UPSTREAM: dmaengine: pl330: Acquire dmac's spinlock in
pl330_tx_status
There is a racing when accessing dmac thread in pl330_tx_status that
@ -946,10 +1103,10 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 2 insertions(+)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 16f578f1d050..642d07412d8d 100644
index aab5abab5a10..1741cfbe311e 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2297,6 +2297,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2290,6 +2290,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
goto out;
spin_lock_irqsave(&pch->lock, flags);
@ -957,7 +1114,7 @@ index 16f578f1d050..642d07412d8d 100644
if (pch->thread->req_running != -1)
running = pch->thread->req[pch->thread->req_running].desc;
@@ -2339,6 +2340,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
@@ -2332,6 +2333,7 @@ pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
if (desc->last)
residual = 0;
}
@ -966,11 +1123,11 @@ index 16f578f1d050..642d07412d8d 100644
out:
From 58befcac6b343442beba9af186e5585c1a159288 Mon Sep 17 00:00:00 2001
From 6e3724a83db9e92e163261bc22c2e3f6f0865e69 Mon Sep 17 00:00:00 2001
From: Stephen Barber <smbarber@chromium.org>
Date: Tue, 1 Nov 2016 16:44:27 -0700
Subject: [PATCH 10/16] UPSTREAM: dmaengine: pl330: Handle xferred count if
DMAMOV hasn't finished
Subject: [PATCH] UPSTREAM: dmaengine: pl330: Handle xferred count if DMAMOV
hasn't finished
After executing DMAGO it's possible that a request can come in for the
current xferred count, but if that happens too soon then DMAMOV SAR/DAR
@ -985,10 +1142,10 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 5 insertions(+)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 642d07412d8d..700abe522316 100644
index 1741cfbe311e..dd58cf886fa0 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2275,6 +2275,11 @@ static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
@@ -2268,6 +2268,11 @@ static int pl330_get_current_xferred_count(struct dma_pl330_chan *pch,
}
pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
pm_runtime_put_autosuspend(pl330->ddma.dev);
@ -1001,11 +1158,10 @@ index 642d07412d8d..700abe522316 100644
}
From e169fa9c6afdc35362da8b6fee2822597400cb8c Mon Sep 17 00:00:00 2001
From 529feba8e68c331c6385d51e820599466a24f6eb Mon Sep 17 00:00:00 2001
From: Vladimir Murzin <vladimir.murzin@arm.com>
Date: Wed, 7 Dec 2016 13:17:40 +0000
Subject: [PATCH 11/16] UPSTREAM: dmaengine: pl330: do not generate unaligned
access
Subject: [PATCH] UPSTREAM: dmaengine: pl330: do not generate unaligned access
When PL330 is used with !MMU the following fault is seen:
@ -1063,7 +1219,7 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 700abe522316..c242c8634a58 100644
index dd58cf886fa0..50a5f8e1e371 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -573,7 +573,8 @@ static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
@ -1104,11 +1260,11 @@ index 700abe522316..c242c8634a58 100644
return SZ_DMAGO;
}
From 39f8d588ba2abc09f8232aab5de223eba7f2511c Mon Sep 17 00:00:00 2001
From 6b7fb23e9950ce28ddc7303236bfe2e8c9505fa9 Mon Sep 17 00:00:00 2001
From: Vinod Koul <vinod.koul@intel.com>
Date: Fri, 9 Dec 2016 15:24:12 +0530
Subject: [PATCH 12/16] =?UTF-8?q?UPSTREAM:=20dmaengine:=20pl330:=20remove?=
=?UTF-8?q?=20unused=20=E2=80=98regs=E2=80=99?=
Subject: [PATCH] =?UTF-8?q?UPSTREAM:=20dmaengine:=20pl330:=20remove=20unus?=
=?UTF-8?q?ed=20=E2=80=98regs=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -1129,10 +1285,10 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 3 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index c242c8634a58..da72d3d984e8 100644
index 50a5f8e1e371..c725ceb4644d 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1891,11 +1891,8 @@ static int dmac_alloc_resources(struct pl330_dmac *pl330)
@@ -1883,11 +1883,8 @@ static int dmac_alloc_resources(struct pl330_dmac *pl330)
static int pl330_add(struct pl330_dmac *pl330)
{
@ -1145,152 +1301,10 @@ index c242c8634a58..da72d3d984e8 100644
if ((pl330->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) {
dev_err(pl330->ddma.dev, "PERIPH_ID 0x%x !\n",
From 8906839d1e7292db9f36ca135d0c640811ac08ee Mon Sep 17 00:00:00 2001
From: Iago Abal <mail@iagoabal.eu>
Date: Wed, 11 Jan 2017 14:00:21 +0100
Subject: [PATCH 13/16] UPSTREAM: dmaengine: pl330: fix double lock
The static bug finder EBA (http://www.iagoabal.eu/eba/) reported the
following double-lock bug:
Double lock:
1. spin_lock_irqsave(pch->lock, flags) at pl330_free_chan_resources:2236;
2. call to function `pl330_release_channel' immediately after;
3. call to function `dma_pl330_rqcb' in line 1753;
4. spin_lock_irqsave(pch->lock, flags) at dma_pl330_rqcb:1505.
I have fixed it as suggested by Marek Szyprowski.
First, I have replaced `pch->lock' with `pl330->lock' in functions
`pl330_alloc_chan_resources' and `pl330_free_chan_resources'. This avoids
the double-lock by acquiring a different lock than `dma_pl330_rqcb'.
NOTE that, as a result, `pl330_free_chan_resources' executes
`list_splice_tail_init' on `pch->work_list' under lock `pl330->lock',
whereas in the rest of the code `pch->work_list' is protected by
`pch->lock'. I don't know if this may cause race conditions. Similarly
`pch->cyclic' is written by `pl330_alloc_chan_resources' under
`pl330->lock' but read by `pl330_tx_submit' under `pch->lock'.
Second, I have removed locking from `pl330_request_channel' and
`pl330_release_channel' functions. Function `pl330_request_channel' is
only called from `pl330_alloc_chan_resources', so the lock is already
held. Function `pl330_release_channel' is called from
`pl330_free_chan_resources', which already holds the lock, and from
`pl330_del'. Function `pl330_del' is called in an error path of
`pl330_probe' and at the end of `pl330_remove', but I assume that there
cannot be concurrent accesses to the protected data at those points.
Signed-off-by: Iago Abal <mail@iagoabal.eu>
Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
(cherry picked from commit 91539eb1fda2d530d3b268eef542c5414e54bf1a)
---
drivers/dma/pl330.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index da72d3d984e8..306186354e00 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1699,7 +1699,6 @@ static bool _chan_ns(const struct pl330_dmac *pl330, int i)
static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
{
struct pl330_thread *thrd = NULL;
- unsigned long flags;
int chans, i;
if (pl330->state == DYING)
@@ -1707,8 +1706,6 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
chans = pl330->pcfg.num_chan;
- spin_lock_irqsave(&pl330->lock, flags);
-
for (i = 0; i < chans; i++) {
thrd = &pl330->channels[i];
if ((thrd->free) && (!_manager_ns(thrd) ||
@@ -1726,8 +1723,6 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
thrd = NULL;
}
- spin_unlock_irqrestore(&pl330->lock, flags);
-
return thrd;
}
@@ -1745,7 +1740,6 @@ static inline void _free_event(struct pl330_thread *thrd, int ev)
static void pl330_release_channel(struct pl330_thread *thrd)
{
struct pl330_dmac *pl330;
- unsigned long flags;
if (!thrd || thrd->free)
return;
@@ -1757,10 +1751,8 @@ static void pl330_release_channel(struct pl330_thread *thrd)
pl330 = thrd->dmac;
- spin_lock_irqsave(&pl330->lock, flags);
_free_event(thrd, thrd->ev);
thrd->free = true;
- spin_unlock_irqrestore(&pl330->lock, flags);
}
/* Initialize the structure for PL330 configuration, that can be used
@@ -2124,20 +2116,20 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
struct pl330_dmac *pl330 = pch->dmac;
unsigned long flags;
- spin_lock_irqsave(&pch->lock, flags);
+ spin_lock_irqsave(&pl330->lock, flags);
dma_cookie_init(chan);
pch->cyclic = false;
pch->thread = pl330_request_channel(pl330);
if (!pch->thread) {
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
return -ENOMEM;
}
tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch);
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
return 1;
}
@@ -2240,12 +2232,13 @@ static int pl330_pause(struct dma_chan *chan)
static void pl330_free_chan_resources(struct dma_chan *chan)
{
struct dma_pl330_chan *pch = to_pchan(chan);
+ struct pl330_dmac *pl330 = pch->dmac;
unsigned long flags;
tasklet_kill(&pch->task);
pm_runtime_get_sync(pch->dmac->ddma.dev);
- spin_lock_irqsave(&pch->lock, flags);
+ spin_lock_irqsave(&pl330->lock, flags);
pl330_release_channel(pch->thread);
pch->thread = NULL;
@@ -2253,7 +2246,7 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
if (pch->cyclic)
list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
pm_runtime_put_autosuspend(pch->dmac->ddma.dev);
}
From e6e9d20e0c601bc33868de2be0831d273851ddb6 Mon Sep 17 00:00:00 2001
From 7c01c9e12f3c5ba64102d9cdf3022427c2cb87dd Mon Sep 17 00:00:00 2001
From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Date: Thu, 1 Jun 2017 19:22:01 +0100
Subject: [PATCH 14/16] UPSTREAM: dmaengine: pl330: fix warning in pl330_remove
Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix warning in pl330_remove
When removing a device with less than 9 IRQs (AMBA_NR_IRQS), we'll get a
big WARN_ON from devres.c because pl330_remove calls devm_free_irqs for
@ -1305,7 +1319,7 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 306186354e00..ddcb8029eddc 100644
index c725ceb4644d..73eaf78871f1 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -3038,7 +3038,8 @@ static int pl330_remove(struct amba_device *adev)
@ -1319,11 +1333,10 @@ index 306186354e00..ddcb8029eddc 100644
dma_async_device_unregister(&pl330->ddma);
From 59636648043a2ed182cf745956cf970702783ffe Mon Sep 17 00:00:00 2001
From e2cdb111e43e8ca7ac2682bb95a7d056e50c847e Mon Sep 17 00:00:00 2001
From: Marek Szyprowski <m.szyprowski@samsung.com>
Date: Mon, 27 Mar 2017 07:31:03 +0200
Subject: [PATCH 15/16] UPSTREAM: dmaengine: pl330: remove pdata based
initialization
Subject: [PATCH] UPSTREAM: dmaengine: pl330: remove pdata based initialization
This driver is now used only on platforms which support device tree, so
it is safe to remove legacy platform data based initialization code.
@ -1355,7 +1368,7 @@ index e212f9d804bd..2ef19ad5cb62 100644
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ddcb8029eddc..2044d36f81b1 100644
index 73eaf78871f1..23fdb826c6e8 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -22,7 +22,6 @@
@ -1499,10 +1512,10 @@ index fe93758e8403..000000000000
-extern bool pl330_filter(struct dma_chan *chan, void *param);
-#endif /* __AMBA_PL330_H_ */
From 163589ea5636b2eeb8d579251465ac1ce0fb0d8e Mon Sep 17 00:00:00 2001
From 9093533777a0b008ac236ddf724312931e76a156 Mon Sep 17 00:00:00 2001
From: Matthias Kaehlcke <mka@chromium.org>
Date: Thu, 15 Jun 2017 16:55:57 -0700
Subject: [PATCH 16/16] UPSTREAM: dmaengine: pl330: Delete unused functions
Subject: [PATCH] UPSTREAM: dmaengine: pl330: Delete unused functions
The functions _queue_empty(), _emit_ADDH(), _emit_NOP(), _emit_STZ()
and _emit_WFE() are not used. Delete them.
@ -1515,7 +1528,7 @@ Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 file changed, 67 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 2044d36f81b1..00ba5db20ec4 100644
index 23fdb826c6e8..51aa1de88007 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -538,11 +538,6 @@ struct _xfer_spec {
@ -1613,3 +1626,160 @@ index 2044d36f81b1..00ba5db20ec4 100644
static inline u32 _emit_WFP(unsigned dry_run, u8 buf[],
enum pl330_cond cond, u8 peri)
{
From f1dc421cf01a6fb47f157f6d15eb50955c9a0aef Mon Sep 17 00:00:00 2001
From: Arvind Yadav <arvind.yadav.cs@gmail.com>
Date: Wed, 23 Aug 2017 21:57:31 +0530
Subject: [PATCH] UPSTREAM: dmaengine: pl330: constify amba_id
amba_id are not supposed to change at runtime. All functions
working with const amba_id. So mark the non-const structs as const.
Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
(cherry picked from commit b753351ec8f4c6a25c6d9b5c4eccce62e448a571)
---
drivers/dma/pl330.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 51aa1de88007..defec1b4bc2f 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2970,7 +2970,7 @@ static int pl330_remove(struct amba_device *adev)
return 0;
}
-static struct amba_id pl330_ids[] = {
+static const struct amba_id pl330_ids[] = {
{
.id = 0x00041330,
.mask = 0x000fffff,
From efc0eb0c26f642db285a449c52d3d571d06206fe Mon Sep 17 00:00:00 2001
From: Alexander Kochetkov <al.kochet@gmail.com>
Date: Wed, 4 Oct 2017 14:37:23 +0300
Subject: [PATCH] UPSTREAM: dmaengine: pl330: fix descriptor allocation fail
If two concurrent threads call pl330_get_desc() when DMAC descriptor
pool is empty it is possible that allocation for one of threads will fail
with message:
kernel: dma-pl330 20078000.dma-controller: pl330_get_desc:2469 ALERT!
Here how that can happen. Thread A calls pl330_get_desc() to get
descriptor. If DMAC descriptor pool is empty pl330_get_desc() allocates
new descriptor on shared pool using add_desc() and then get newly
allocated descriptor using pluck_desc(). At the same time thread B calls
pluck_desc() and take newly allocated descriptor. In that case descriptor
allocation for thread A will fail.
Using on-stack pool for new descriptor allow avoid the issue described.
The patch modify pl330_get_desc() to use on-stack pool for allocation
new descriptors.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
(cherry picked from commit e588710311ee5bece284871d613418831d56f2bd)
---
drivers/dma/pl330.c | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index defec1b4bc2f..76f514efe9d0 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -2338,7 +2338,8 @@ static inline void _init_desc(struct dma_pl330_desc *desc)
}
/* Returns the number of descriptors added to the DMAC pool */
-static int add_desc(struct pl330_dmac *pl330, gfp_t flg, int count)
+static int add_desc(struct list_head *pool, spinlock_t *lock,
+ gfp_t flg, int count)
{
struct dma_pl330_desc *desc;
unsigned long flags;
@@ -2348,27 +2349,28 @@ static int add_desc(struct pl330_dmac *pl330, gfp_t flg, int count)
if (!desc)
return 0;
- spin_lock_irqsave(&pl330->pool_lock, flags);
+ spin_lock_irqsave(lock, flags);
for (i = 0; i < count; i++) {
_init_desc(&desc[i]);
- list_add_tail(&desc[i].node, &pl330->desc_pool);
+ list_add_tail(&desc[i].node, pool);
}
- spin_unlock_irqrestore(&pl330->pool_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
return count;
}
-static struct dma_pl330_desc *pluck_desc(struct pl330_dmac *pl330)
+static struct dma_pl330_desc *pluck_desc(struct list_head *pool,
+ spinlock_t *lock)
{
struct dma_pl330_desc *desc = NULL;
unsigned long flags;
- spin_lock_irqsave(&pl330->pool_lock, flags);
+ spin_lock_irqsave(lock, flags);
- if (!list_empty(&pl330->desc_pool)) {
- desc = list_entry(pl330->desc_pool.next,
+ if (!list_empty(pool)) {
+ desc = list_entry(pool->next,
struct dma_pl330_desc, node);
list_del_init(&desc->node);
@@ -2377,7 +2379,7 @@ static struct dma_pl330_desc *pluck_desc(struct pl330_dmac *pl330)
desc->txd.callback = NULL;
}
- spin_unlock_irqrestore(&pl330->pool_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
return desc;
}
@@ -2389,20 +2391,18 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
struct dma_pl330_desc *desc;
/* Pluck one desc from the pool of DMAC */
- desc = pluck_desc(pl330);
+ desc = pluck_desc(&pl330->desc_pool, &pl330->pool_lock);
/* If the DMAC pool is empty, alloc new */
if (!desc) {
- if (!add_desc(pl330, GFP_ATOMIC, 1))
- return NULL;
+ DEFINE_SPINLOCK(lock);
+ LIST_HEAD(pool);
- /* Try again */
- desc = pluck_desc(pl330);
- if (!desc) {
- dev_err(pch->dmac->ddma.dev,
- "%s:%d ALERT!\n", __func__, __LINE__);
+ if (!add_desc(&pool, &lock, GFP_ATOMIC, 1))
return NULL;
- }
+
+ desc = pluck_desc(&pool, &lock);
+ WARN_ON(!desc || !list_empty(&pool));
}
/* Initialize the descriptor */
@@ -2815,7 +2815,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&pl330->pool_lock);
/* Create a descriptor pool of default size */
- if (!add_desc(pl330, GFP_KERNEL, NR_DEFAULT_DESC))
+ if (!add_desc(&pl330->desc_pool, &pl330->pool_lock,
+ GFP_KERNEL, NR_DEFAULT_DESC))
dev_warn(&adev->dev, "unable to allocate desc\n");
INIT_LIST_HEAD(&pd->channels);