From c8f15e5ff0fdf570b12748e9492ed4c647e961e7 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Fri, 12 May 2017 07:33:41 +0200 Subject: [PATCH] Add several DVB drivers. https://forum.armbian.com/index.php?/topic/4248-tinkerboard-dvb-drivers Removing deprecated patches, added upstream patch. --- config/kernel/linux-rockchip-default.config | 197 +++- config/kernel/linux-rockchip-next.config | 184 +++- .../rockchip-default/03-patch-4.4.66-67.patch | 948 ++++++++++++++++++ ..._eeprom_add_read_and_write_functions.patch | 97 -- .../set_ethaddr_in_late_init.patch | 91 -- 5 files changed, 1317 insertions(+), 200 deletions(-) create mode 100644 patch/kernel/rockchip-default/03-patch-4.4.66-67.patch delete mode 100644 patch/u-boot/u-boot-rockchip/i2c_eeprom_add_read_and_write_functions.patch delete mode 100644 patch/u-boot/u-boot-rockchip/set_ethaddr_in_late_init.patch diff --git a/config/kernel/linux-rockchip-default.config b/config/kernel/linux-rockchip-default.config index b7fb90a93..fad3a3985 100644 --- a/config/kernel/linux-rockchip-default.config +++ b/config/kernel/linux-rockchip-default.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.4.61 Kernel Configuration +# Linux/arm 4.4.67 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -564,11 +564,11 @@ CONFIG_CPU_FREQ_GOV_COMMON=y CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_SCHED is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y @@ -2501,7 +2501,7 @@ CONFIG_MEDIA_SUPPORT=y # CONFIG_MEDIA_CAMERA_SUPPORT=y # CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set # CONFIG_MEDIA_RC_SUPPORT is not set @@ -2510,11 +2510,18 @@ CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_CONTIG=m CONFIG_VIDEOBUF2_CORE=y CONFIG_VIDEOBUF2_MEMOPS=y CONFIG_VIDEOBUF2_DMA_CONTIG=y CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_DVB_CORE=y +CONFIG_DVB_NET=y # CONFIG_TTPCI_EEPROM is not set +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set # # Media drivers @@ -2534,11 +2541,39 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_S2255 is not set # CONFIG_VIDEO_USBTV is not set +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y + +# +# Digital TV USB devices +# +CONFIG_DVB_USB_V2=y +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + # # Webcam, TV (analog/digital) USB devices # # CONFIG_VIDEO_EM28XX is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_PLATFORM=m CONFIG_V4L_MEM2MEM_DRIVERS=y # CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set # CONFIG_VIDEO_SH_VEU is not set @@ -2546,16 +2581,29 @@ CONFIG_VIDEO_ROCKCHIP_VPU=y CONFIG_V4L_TEST_DRIVERS=y # CONFIG_VIDEO_VIVID is not set # CONFIG_VIDEO_VIM2M is not set +CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_DVB_C8SECTPFE=m # # Supported MMC/SDIO adapters # -# CONFIG_CYPRESS_FIRMWARE is not set +CONFIG_SMS_SDIO_DRV=m +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +# CONFIG_SMS_SIANO_DEBUGFS is not set # # Media ancillary drivers (tuners, sensors, i2c, frontends) # CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y # # Audio decoders, processors and mixers @@ -2601,12 +2649,145 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y # Sensors used on soc_camera driver # +# +# soc_camera sensor drivers +# +CONFIG_SOC_CAMERA_IMX074=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_MT9T112=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_OV2640=m +CONFIG_SOC_CAMERA_OV5642=m +CONFIG_SOC_CAMERA_OV6650=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_SOC_CAMERA_OV9640=m +CONFIG_SOC_CAMERA_OV9740=m +CONFIG_SOC_CAMERA_RJ54N1=m +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_TS2020=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m + +# +# ISDB-T (terrestrial) frontends +# + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_SP2=m +CONFIG_DVB_AF9033=m + # # Tools to develop new frontends # # CONFIG_DVB_DUMMY_FE is not set # CONFIG_CAMSYS_DRV is not set -# CONFIG_ROCK_CHIP_SOC_CAMERA is not set +CONFIG_ROCK_CHIP_SOC_CAMERA=m + +# +# rockchip camera sensor interface driver +# +# CONFIG_ROCKCHIP_CAMERA_SENSOR_INTERFACE is not set +# CONFIG_RK30_CAMERA_ONEFRAME is not set +# CONFIG_RK30_CAMERA_PINGPONG is not set # # Graphics support @@ -3127,7 +3308,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_UAS is not set +CONFIG_USB_UAS=m # # USB Imaging devices diff --git a/config/kernel/linux-rockchip-next.config b/config/kernel/linux-rockchip-next.config index 1929bd0b0..772b5ab74 100644 --- a/config/kernel/linux-rockchip-next.config +++ b/config/kernel/linux-rockchip-next.config @@ -2589,7 +2589,7 @@ CONFIG_MEDIA_SUPPORT=y # CONFIG_MEDIA_CAMERA_SUPPORT=y # CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set # CONFIG_MEDIA_RC_SUPPORT is not set @@ -2599,10 +2599,17 @@ CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF2_CORE=y CONFIG_VIDEOBUF2_MEMOPS=y CONFIG_VIDEOBUF2_VMALLOC=y +CONFIG_DVB_CORE=y +CONFIG_DVB_NET=y # CONFIG_TTPCI_EEPROM is not set +CONFIG_DVB_MAX_ADAPTERS=16 +CONFIG_DVB_DYNAMIC_MINORS=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set # # Media drivers @@ -2622,27 +2629,68 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_S2255 is not set # CONFIG_VIDEO_USBTV is not set +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y + +# +# Digital TV USB devices +# +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_DVBSKY=m +CONFIG_DVB_USB_ZD1301=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +CONFIG_DVB_AS102=m + # # Webcam, TV (analog/digital) USB devices # # CONFIG_VIDEO_EM28XX is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_PLATFORM=m CONFIG_V4L_MEM2MEM_DRIVERS=y # CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set # CONFIG_VIDEO_SH_VEU is not set CONFIG_V4L_TEST_DRIVERS=y # CONFIG_VIDEO_VIVID is not set # CONFIG_VIDEO_VIM2M is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set # # Supported MMC/SDIO adapters # -# CONFIG_CYPRESS_FIRMWARE is not set +CONFIG_SMS_SDIO_DRV=m +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_SMS_SIANO_MDTV=m +# CONFIG_SMS_SIANO_DEBUGFS is not set # # Media ancillary drivers (tuners, sensors, i2c, spi, frontends) # CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y # # Audio decoders, processors and mixers @@ -2667,6 +2715,7 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y # # Camera sensor devices # +CONFIG_VIDEO_MT9M111=m # # Flash devices @@ -2688,9 +2737,136 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y # Sensors used on soc_camera driver # +# +# soc_camera sensor drivers +# +CONFIG_SOC_CAMERA_IMX074=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_MT9T112=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_OV2640=m +CONFIG_SOC_CAMERA_OV5642=m +CONFIG_SOC_CAMERA_OV6650=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_SOC_CAMERA_OV9640=m +CONFIG_SOC_CAMERA_OV9740=m +CONFIG_SOC_CAMERA_RJ54N1=m +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=y +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_TS2020=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_AS102_FE=m +CONFIG_DVB_ZD1301_DEMOD=m +# CONFIG_DVB_GP8PSK_FE is not set + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m + +# +# ISDB-T (terrestrial) frontends +# + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_SP2=m +CONFIG_DVB_AF9033=m + # # Tools to develop new frontends # +# CONFIG_DVB_DUMMY_FE is not set # # Graphics support @@ -3197,7 +3373,7 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_UAS is not set +CONFIG_USB_UAS=m # # USB Imaging devices diff --git a/patch/kernel/rockchip-default/03-patch-4.4.66-67.patch b/patch/kernel/rockchip-default/03-patch-4.4.66-67.patch new file mode 100644 index 000000000..aafd894f6 --- /dev/null +++ b/patch/kernel/rockchip-default/03-patch-4.4.66-67.patch @@ -0,0 +1,948 @@ +diff --git a/Makefile b/Makefile +index 1cd052823c03..c987902ae1ee 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 66 ++SUBLEVEL = 67 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c +index 9462d2752850..8bdc34dbaedf 100644 +--- a/drivers/block/drbd/drbd_bitmap.c ++++ b/drivers/block/drbd/drbd_bitmap.c +@@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device) + * this masks out the remaining bits. + * Returns the number of bits cleared. + */ ++#ifndef BITS_PER_PAGE + #define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3)) + #define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1) ++#else ++# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3)) ++# error "ambiguous BITS_PER_PAGE" ++# endif ++#endif + #define BITS_PER_LONG_MASK (BITS_PER_LONG - 1) + static int bm_clear_surplus(struct drbd_bitmap *b) + { +diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c +index 3eff35c2d453..2684605fe67f 100644 +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -41,13 +41,13 @@ + + #include "qib.h" + +-#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) +-#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) ++#define RVT_BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) ++#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE-1) + + static inline unsigned mk_qpn(struct qib_qpn_table *qpt, + struct qpn_map *map, unsigned off) + { +- return (map - qpt->map) * BITS_PER_PAGE + off; ++ return (map - qpt->map) * RVT_BITS_PER_PAGE + off; + } + + static inline unsigned find_next_offset(struct qib_qpn_table *qpt, +@@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt, + if (((off & qpt->mask) >> 1) >= n) + off = (off | qpt->mask) + 2; + } else +- off = find_next_zero_bit(map->page, BITS_PER_PAGE, off); ++ off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off); + return off; + } + +@@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, + qpn = 2; + if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues) + qpn = (qpn | qpt->mask) + 2; +- offset = qpn & BITS_PER_PAGE_MASK; +- map = &qpt->map[qpn / BITS_PER_PAGE]; ++ offset = qpn & RVT_BITS_PER_PAGE_MASK; ++ map = &qpt->map[qpn / RVT_BITS_PER_PAGE]; + max_scan = qpt->nmaps - !offset; + for (i = 0;;) { + if (unlikely(!map->page)) { +@@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, + * We just need to be sure we don't loop + * forever. + */ +- } while (offset < BITS_PER_PAGE && qpn < QPN_MAX); ++ } while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX); + /* + * In order to keep the number of pages allocated to a + * minimum, we scan the all existing pages before increasing +@@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn) + { + struct qpn_map *map; + +- map = qpt->map + qpn / BITS_PER_PAGE; ++ map = qpt->map + qpn / RVT_BITS_PER_PAGE; + if (map->page) +- clear_bit(qpn & BITS_PER_PAGE_MASK, map->page); ++ clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page); + } + + static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn) +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index 80a439543259..e503279c34fc 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) + if (r) + goto out; + +- param->data_size = sizeof(*param); ++ param->data_size = offsetof(struct dm_ioctl, data); + r = fn(param, input_param_size); + + if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && +diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig +index 54479c481a7a..8a25adced79f 100644 +--- a/drivers/mtd/chips/Kconfig ++++ b/drivers/mtd/chips/Kconfig +@@ -111,6 +111,7 @@ config MTD_MAP_BANK_WIDTH_16 + + config MTD_MAP_BANK_WIDTH_32 + bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY ++ select MTD_COMPLEX_MAPPINGS if HAS_IOMEM + default n + help + If you wish to support CFI devices on a physical bus which is +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 49056c33be74..21e5b9ed1ead 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -12031,7 +12031,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + int ret; + u32 offset, len, b_offset, odd_len; + u8 *buf; +- __be32 start, end; ++ __be32 start = 0, end; + + if (tg3_flag(tp, NO_NVRAM) || + eeprom->magic != TG3_EEPROM_MAGIC) +diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c +index 2882bcac918a..0b096730c72a 100644 +--- a/drivers/scsi/cxlflash/main.c ++++ b/drivers/scsi/cxlflash/main.c +@@ -996,6 +996,8 @@ static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) + do { + msleep(delay_us / 1000); + status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); ++ if (status == U64_MAX) ++ nretry /= 2; + } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_ONLINE && + nretry--); + +@@ -1027,6 +1029,8 @@ static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) + do { + msleep(delay_us / 1000); + status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); ++ if (status == U64_MAX) ++ nretry /= 2; + } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_OFFLINE && + nretry--); + +@@ -1137,7 +1141,7 @@ static const struct asyc_intr_info ainfo[] = { + {SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR}, + {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST}, + {SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0}, +- {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST}, ++ {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0}, + {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, + {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, + {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, +@@ -1145,7 +1149,7 @@ static const struct asyc_intr_info ainfo[] = { + {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, + {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, + {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, +- {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST}, ++ {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0}, + {0x0, "", 0, 0} /* terminator */ + }; + +@@ -1962,6 +1966,11 @@ retry: + * cxlflash_eh_host_reset_handler() - reset the host adapter + * @scp: SCSI command from stack identifying host. + * ++ * Following a reset, the state is evaluated again in case an EEH occurred ++ * during the reset. In such a scenario, the host reset will either yield ++ * until the EEH recovery is complete or return success or failure based ++ * upon the current device state. ++ * + * Return: + * SUCCESS as defined in scsi/scsi.h + * FAILED as defined in scsi/scsi.h +@@ -1993,7 +2002,8 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp) + } else + cfg->state = STATE_NORMAL; + wake_up_all(&cfg->reset_waitq); +- break; ++ ssleep(1); ++ /* fall through */ + case STATE_RESET: + wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); + if (cfg->state == STATE_NORMAL) +@@ -2534,6 +2544,9 @@ static void drain_ioctls(struct cxlflash_cfg *cfg) + * @pdev: PCI device struct. + * @state: PCI channel state. + * ++ * When an EEH occurs during an active reset, wait until the reset is ++ * complete and then take action based upon the device state. ++ * + * Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT + */ + static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, +@@ -2547,6 +2560,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, + + switch (state) { + case pci_channel_io_frozen: ++ wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); ++ if (cfg->state == STATE_FAILTERM) ++ return PCI_ERS_RESULT_DISCONNECT; ++ + cfg->state = STATE_RESET; + scsi_block_requests(cfg->host); + drain_ioctls(cfg); +diff --git a/drivers/staging/rdma/ehca/ehca_mrmw.c b/drivers/staging/rdma/ehca/ehca_mrmw.c +index f914b30999f8..4d52ca42644a 100644 +--- a/drivers/staging/rdma/ehca/ehca_mrmw.c ++++ b/drivers/staging/rdma/ehca/ehca_mrmw.c +@@ -1921,7 +1921,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, + u64 *kpage) + { + int ret = 0; +- u64 pgaddr, prev_pgaddr; ++ u64 pgaddr, prev_pgaddr = 0; + u32 j = 0; + int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE; + int nr_kpages = kpages_per_hwpage; +@@ -2417,6 +2417,7 @@ static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca, + ehca_err(&shca->ib_device, "kpage alloc failed"); + return -ENOMEM; + } ++ hret = H_SUCCESS; + for (top = 0; top < EHCA_MAP_ENTRIES; top++) { + if (!ehca_bmap_valid(ehca_bmap->top[top])) + continue; +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 83ff1724ec79..cf3da51a3536 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -5850,17 +5850,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) + static void serial8250_io_resume(struct pci_dev *dev) + { + struct serial_private *priv = pci_get_drvdata(dev); +- const struct pciserial_board *board; ++ struct serial_private *new; + + if (!priv) + return; + +- board = priv->board; +- kfree(priv); +- priv = pciserial_init_ports(dev, board); +- +- if (!IS_ERR(priv)) { +- pci_set_drvdata(dev, priv); ++ new = pciserial_init_ports(dev, priv->board); ++ if (!IS_ERR(new)) { ++ pci_set_drvdata(dev, new); ++ kfree(priv); + } + } + +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 94906aaa9b7c..e2f6a79e9b01 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -227,6 +227,7 @@ struct smb_version_operations { + /* verify the message */ + int (*check_message)(char *, unsigned int); + bool (*is_oplock_break)(char *, struct TCP_Server_Info *); ++ int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *, + struct cifsInodeInfo *, bool); + /* process transaction2 response */ +@@ -1289,12 +1290,19 @@ struct mid_q_entry { + void *callback_data; /* general purpose pointer for callback */ + void *resp_buf; /* pointer to received SMB header */ + int mid_state; /* wish this were enum but can not pass to wait_event */ ++ unsigned int mid_flags; + __le16 command; /* smb command code */ + bool large_buf:1; /* if valid response, is pointer to large buf */ + bool multiRsp:1; /* multiple trans2 responses for one request */ + bool multiEnd:1; /* both received */ + }; + ++struct close_cancelled_open { ++ struct cifs_fid fid; ++ struct cifs_tcon *tcon; ++ struct work_struct work; ++}; ++ + /* Make code in transport.c a little cleaner by moving + update of optional stats into function below */ + #ifdef CONFIG_CIFS_STATS2 +@@ -1426,6 +1434,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, + #define MID_RESPONSE_MALFORMED 0x10 + #define MID_SHUTDOWN 0x20 + ++/* Flags */ ++#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ ++ + /* Types of response buffer returned from SendReceive2 */ + #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ + #define CIFS_SMALL_BUFFER 1 +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index b1104ed8f54c..5e2f8b8ca08a 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1424,6 +1424,8 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) + + length = discard_remaining_data(server); + dequeue_mid(mid, rdata->result); ++ mid->resp_buf = server->smallbuf; ++ server->smallbuf = NULL; + return length; + } + +@@ -1538,6 +1540,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + return cifs_readv_discard(server, mid); + + dequeue_mid(mid, false); ++ mid->resp_buf = server->smallbuf; ++ server->smallbuf = NULL; + return length; + } + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 5d59f25521ce..156bc18eac69 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -924,10 +924,19 @@ cifs_demultiplex_thread(void *p) + + server->lstrp = jiffies; + if (mid_entry != NULL) { ++ if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && ++ mid_entry->mid_state == MID_RESPONSE_RECEIVED && ++ server->ops->handle_cancelled_mid) ++ server->ops->handle_cancelled_mid( ++ mid_entry->resp_buf, ++ server); ++ + if (!mid_entry->multiRsp || mid_entry->multiEnd) + mid_entry->callback(mid_entry); +- } else if (!server->ops->is_oplock_break || +- !server->ops->is_oplock_break(buf, server)) { ++ } else if (server->ops->is_oplock_break && ++ server->ops->is_oplock_break(buf, server)) { ++ cifs_dbg(FYI, "Received oplock break\n"); ++ } else { + cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n", + atomic_read(&midCount)); + cifs_dump_mem("Received Data is: ", buf, +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index e5bc85e49be7..76ccf20fbfb7 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -630,3 +630,47 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) + cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); + return false; + } ++ ++void ++smb2_cancelled_close_fid(struct work_struct *work) ++{ ++ struct close_cancelled_open *cancelled = container_of(work, ++ struct close_cancelled_open, work); ++ ++ cifs_dbg(VFS, "Close unmatched open\n"); ++ ++ SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid, ++ cancelled->fid.volatile_fid); ++ cifs_put_tcon(cancelled->tcon); ++ kfree(cancelled); ++} ++ ++int ++smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) ++{ ++ struct smb2_hdr *hdr = (struct smb2_hdr *)buffer; ++ struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; ++ struct cifs_tcon *tcon; ++ struct close_cancelled_open *cancelled; ++ ++ if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS) ++ return 0; ++ ++ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); ++ if (!cancelled) ++ return -ENOMEM; ++ ++ tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId); ++ if (!tcon) { ++ kfree(cancelled); ++ return -ENOENT; ++ } ++ ++ cancelled->fid.persistent_fid = rsp->PersistentFileId; ++ cancelled->fid.volatile_fid = rsp->VolatileFileId; ++ cancelled->tcon = tcon; ++ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); ++ queue_work(cifsiod_wq, &cancelled->work); ++ ++ return 0; ++} +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index be34b4860675..087918c4612a 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1511,6 +1511,7 @@ struct smb_version_operations smb20_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1589,6 +1590,7 @@ struct smb_version_operations smb21_operations = { + .clear_stats = smb2_clear_stats, + .print_stats = smb2_print_stats, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1670,6 +1672,7 @@ struct smb_version_operations smb30_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +@@ -1757,6 +1760,7 @@ struct smb_version_operations smb311_operations = { + .print_stats = smb2_print_stats, + .dump_share_caps = smb2_dump_share_caps, + .is_oplock_break = smb2_is_valid_oplock_break, ++ .handle_cancelled_mid = smb2_handle_cancelled_mid, + .downgrade_oplock = smb2_downgrade_oplock, + .need_neg = smb2_need_neg, + .negotiate = smb2_negotiate, +diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h +index 0a406ae78129..adc5234486c3 100644 +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, + struct smb_rqst *rqst); + extern struct mid_q_entry *smb2_setup_async_request( + struct TCP_Server_Info *server, struct smb_rqst *rqst); ++extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, ++ __u64 ses_id); ++extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, ++ __u64 ses_id, __u32 tid); + extern int smb2_calc_signature(struct smb_rqst *rqst, + struct TCP_Server_Info *server); + extern int smb3_calc_signature(struct smb_rqst *rqst, +@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, + extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, + const u64 persistent_fid, const u64 volatile_fid, + const __u8 oplock_level); ++extern int smb2_handle_cancelled_mid(char *buffer, ++ struct TCP_Server_Info *server); ++void smb2_cancelled_close_fid(struct work_struct *work); + extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id, + struct kstatfs *FSData); +diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c +index d4c5b6f109a7..69e3b322bbfe 100644 +--- a/fs/cifs/smb2transport.c ++++ b/fs/cifs/smb2transport.c +@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) + } + + static struct cifs_ses * +-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server) ++smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) + { + struct cifs_ses *ses; + +- spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { +- if (ses->Suid != smb2hdr->SessionId) ++ if (ses->Suid != ses_id) + continue; +- spin_unlock(&cifs_tcp_ses_lock); + return ses; + } ++ ++ return NULL; ++} ++ ++struct cifs_ses * ++smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++{ ++ struct cifs_ses *ses; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); + spin_unlock(&cifs_tcp_ses_lock); + ++ return ses; ++} ++ ++static struct cifs_tcon * ++smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid) ++{ ++ struct cifs_tcon *tcon; ++ ++ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { ++ if (tcon->tid != tid) ++ continue; ++ ++tcon->tc_count; ++ return tcon; ++ } ++ + return NULL; + } + ++/* ++ * Obtain tcon corresponding to the tid in the given ++ * cifs_ses ++ */ ++ ++struct cifs_tcon * ++smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) ++{ ++ struct cifs_ses *ses; ++ struct cifs_tcon *tcon; ++ ++ spin_lock(&cifs_tcp_ses_lock); ++ ses = smb2_find_smb_ses_unlocked(server, ses_id); ++ if (!ses) { ++ spin_unlock(&cifs_tcp_ses_lock); ++ return NULL; ++ } ++ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); ++ spin_unlock(&cifs_tcp_ses_lock); ++ ++ return tcon; ++} + + int + smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) +@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) + struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; + struct cifs_ses *ses; + +- ses = smb2_find_smb_ses(smb2_pdu, server); ++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); + if (!ses) { + cifs_dbg(VFS, "%s: Could not find session\n", __func__); + return 0; +@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) + struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; + struct cifs_ses *ses; + +- ses = smb2_find_smb_ses(smb2_pdu, server); ++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); + if (!ses) { + cifs_dbg(VFS, "%s: Could not find session\n", __func__); + return 0; +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 87abe8ed074c..54af10204e83 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -786,9 +786,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, + + rc = wait_for_response(ses->server, midQ); + if (rc != 0) { ++ cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid); + send_cancel(ses->server, buf, midQ); + spin_lock(&GlobalMid_Lock); + if (midQ->mid_state == MID_REQUEST_SUBMITTED) { ++ midQ->mid_flags |= MID_WAIT_CANCELLED; + midQ->callback = DeleteMidQEntry; + spin_unlock(&GlobalMid_Lock); + cifs_small_buf_release(buf); +diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c +index 1a0835073663..9d6c2dcf1bd0 100644 +--- a/fs/ext4/crypto.c ++++ b/fs/ext4/crypto.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "ext4_extents.h" + #include "xattr.h" +@@ -469,3 +470,61 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size) + return size; + return 0; + } ++ ++/* ++ * Validate dentries for encrypted directories to make sure we aren't ++ * potentially caching stale data after a key has been added or ++ * removed. ++ */ ++static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ struct dentry *dir; ++ struct ext4_crypt_info *ci; ++ int dir_has_key, cached_with_key; ++ ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ ++ dir = dget_parent(dentry); ++ if (!ext4_encrypted_inode(d_inode(dir))) { ++ dput(dir); ++ return 0; ++ } ++ ci = EXT4_I(d_inode(dir))->i_crypt_info; ++ ++ /* this should eventually be an flag in d_flags */ ++ cached_with_key = dentry->d_fsdata != NULL; ++ dir_has_key = (ci != NULL); ++ dput(dir); ++ ++ /* ++ * If the dentry was cached without the key, and it is a ++ * negative dentry, it might be a valid name. We can't check ++ * if the key has since been made available due to locking ++ * reasons, so we fail the validation so ext4_lookup() can do ++ * this check. ++ * ++ * We also fail the validation if the dentry was created with ++ * the key present, but we no longer have the key, or vice versa. ++ */ ++ if ((!cached_with_key && d_is_negative(dentry)) || ++ (!cached_with_key && dir_has_key) || ++ (cached_with_key && !dir_has_key)) { ++#if 0 /* Revalidation debug */ ++ char buf[80]; ++ char *cp = simple_dname(dentry, buf, sizeof(buf)); ++ ++ if (IS_ERR(cp)) ++ cp = (char *) "???"; ++ pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata, ++ cached_with_key, d_is_negative(dentry), ++ dir_has_key); ++#endif ++ return 0; ++ } ++ return 1; ++} ++ ++const struct dentry_operations ext4_encrypted_d_ops = { ++ .d_revalidate = ext4_d_revalidate, ++}; +diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c +index 1d1bca74f844..6d17f31a31d7 100644 +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) + int dir_has_error = 0; + struct ext4_str fname_crypto_str = {.name = NULL, .len = 0}; + ++ if (ext4_encrypted_inode(inode)) { ++ err = ext4_get_encryption_info(inode); ++ if (err && err != -ENOKEY) ++ return err; ++ } ++ + if (is_dx_dir(inode)) { + err = ext4_dx_readdir(file, ctx); + if (err != ERR_BAD_DX_DIR) { +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 362d59b24f1d..3de9bb357b4f 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *inode, + struct page *plaintext_page); + int ext4_decrypt(struct page *page); + int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex); ++extern const struct dentry_operations ext4_encrypted_d_ops; + + #ifdef CONFIG_EXT4_FS_ENCRYPTION + int ext4_init_crypto(void); +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 789e2d6724a9..bcd7c4788903 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -622,6 +622,9 @@ resizefs_out: + struct ext4_encryption_policy policy; + int err = 0; + ++ if (!ext4_has_feature_encrypt(sb)) ++ return -EOPNOTSUPP; ++ + if (copy_from_user(&policy, + (struct ext4_encryption_policy __user *)arg, + sizeof(policy))) { +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 573b4cbb0cb9..fafa903ab3c0 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi + struct ext4_dir_entry_2 *de; + struct buffer_head *bh; + ++ if (ext4_encrypted_inode(dir)) { ++ int res = ext4_get_encryption_info(dir); ++ ++ /* ++ * This should be a properly defined flag for ++ * dentry->d_flags when we uplift this to the VFS. ++ * d_fsdata is set to (void *) 1 if if the dentry is ++ * created while the directory was encrypted and we ++ * don't have access to the key. ++ */ ++ dentry->d_fsdata = NULL; ++ if (ext4_encryption_info(dir)) ++ dentry->d_fsdata = (void *) 1; ++ d_set_d_op(dentry, &ext4_encrypted_d_ops); ++ if (res && res != -ENOKEY) ++ return ERR_PTR(res); ++ } ++ + if (dentry->d_name.len > EXT4_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + +diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c +index 00575d776d91..7162ab7bc093 100644 +--- a/fs/nfsd/nfs3xdr.c ++++ b/fs/nfsd/nfs3xdr.c +@@ -358,6 +358,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + { + unsigned int len, v, hdr, dlen; + u32 max_blocksize = svc_max_payload(rqstp); ++ struct kvec *head = rqstp->rq_arg.head; + + p = decode_fh(p, &args->fh); + if (!p) +@@ -367,6 +368,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + args->count = ntohl(*p++); + args->stable = ntohl(*p++); + len = args->len = ntohl(*p++); ++ if ((void *)p > head->iov_base + head->iov_len) ++ return 0; + /* + * The count must equal the amount of data passed. + */ +@@ -377,9 +380,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- - hdr; ++ hdr = (void*)p - head->iov_base; ++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + /* + * Round the length of the data which was specified up to + * the next multiple of XDR units and then compare that +@@ -396,7 +398,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + len = args->len = max_blocksize; + } + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +@@ -471,6 +473,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, + /* first copy and check from the first page */ + old = (char*)p; + vec = &rqstp->rq_arg.head[0]; ++ if ((void *)old > vec->iov_base + vec->iov_len) ++ return 0; + avail = vec->iov_len - (old - (char*)vec->iov_base); + while (len && avail && *old) { + *new++ = *old++; +diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c +index 79d964aa8079..bf913201a6ad 100644 +--- a/fs/nfsd/nfsxdr.c ++++ b/fs/nfsd/nfsxdr.c +@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + struct nfsd_writeargs *args) + { + unsigned int len, hdr, dlen; ++ struct kvec *head = rqstp->rq_arg.head; + int v; + + p = decode_fh(p, &args->fh); +@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + * Check to make sure that we got the right number of + * bytes. + */ +- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; +- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len +- - hdr; ++ hdr = (void*)p - head->iov_base; ++ if (hdr > head->iov_len) ++ return 0; ++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; + + /* + * Round the length of the data which was specified up to +@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, + return 0; + + rqstp->rq_vec[0].iov_base = (void*)p; +- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; ++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; + v = 0; + while (len > rqstp->rq_vec[v].iov_len) { + len -= rqstp->rq_vec[v].iov_len; +diff --git a/fs/timerfd.c b/fs/timerfd.c +index 053818dd6c18..1327a02ec778 100644 +--- a/fs/timerfd.c ++++ b/fs/timerfd.c +@@ -40,6 +40,7 @@ struct timerfd_ctx { + short unsigned settime_flags; /* to show in fdinfo */ + struct rcu_head rcu; + struct list_head clist; ++ spinlock_t cancel_lock; + bool might_cancel; + }; + +@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void) + rcu_read_unlock(); + } + +-static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++static void __timerfd_remove_cancel(struct timerfd_ctx *ctx) + { + if (ctx->might_cancel) { + ctx->might_cancel = false; +@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx) + } + } + ++static void timerfd_remove_cancel(struct timerfd_ctx *ctx) ++{ ++ spin_lock(&ctx->cancel_lock); ++ __timerfd_remove_cancel(ctx); ++ spin_unlock(&ctx->cancel_lock); ++} ++ + static bool timerfd_canceled(struct timerfd_ctx *ctx) + { + if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) +@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) + + static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + { ++ spin_lock(&ctx->cancel_lock); + if ((ctx->clockid == CLOCK_REALTIME || + ctx->clockid == CLOCK_REALTIME_ALARM) && + (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { +@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) + list_add_rcu(&ctx->clist, &cancel_list); + spin_unlock(&cancel_lock); + } +- } else if (ctx->might_cancel) { +- timerfd_remove_cancel(ctx); ++ } else { ++ __timerfd_remove_cancel(ctx); + } ++ spin_unlock(&ctx->cancel_lock); + } + + static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) +@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) + return -ENOMEM; + + init_waitqueue_head(&ctx->wqh); ++ spin_lock_init(&ctx->cancel_lock); + ctx->clockid = clockid; + + if (isalarm(ctx)) +diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h +index 366cf77953b5..806d0ab845e0 100644 +--- a/include/linux/mtd/map.h ++++ b/include/linux/mtd/map.h +@@ -122,18 +122,13 @@ + #endif + + #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 +-# ifdef map_bankwidth +-# undef map_bankwidth +-# define map_bankwidth(map) ((map)->bankwidth) +-# undef map_bankwidth_is_large +-# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) +-# undef map_words +-# define map_words(map) map_calc_words(map) +-# else +-# define map_bankwidth(map) 32 +-# define map_bankwidth_is_large(map) (1) +-# define map_words(map) map_calc_words(map) +-# endif ++/* always use indirect access for 256-bit to preserve kernel stack */ ++# undef map_bankwidth ++# define map_bankwidth(map) ((map)->bankwidth) ++# undef map_bankwidth_is_large ++# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) ++# undef map_words ++# define map_words(map) map_calc_words(map) + #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) + #undef MAX_MAP_BANKWIDTH + #define MAX_MAP_BANKWIDTH 32 +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 8e33019d8e7b..acfb16fdcd55 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2107,7 +2107,7 @@ static int netlink_dump(struct sock *sk) + if (!skb) { + alloc_size = alloc_min_size; + skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, +- (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM)); ++ GFP_KERNEL); + } + if (!skb) + goto errout_skb; +diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c +index 09da7b52bc2e..1468e4b7bf93 100644 +--- a/sound/ppc/awacs.c ++++ b/sound/ppc/awacs.c +@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) + if (err < 0) + return err; + } ++ master_vol = NULL; + if (pm7500) + err = build_mixers(chip, + ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500), +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index 7a5c9a36c1db..daba8c56b43b 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -139,7 +139,7 @@ static struct snd_soc_dai_link byt_dailink[] = { + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", +- .ignore_suspend = 1, ++ .nonatomic = true, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, +@@ -166,6 +166,7 @@ static struct snd_soc_dai_link byt_dailink[] = { + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_codec_fixup, + .ignore_suspend = 1, ++ .nonatomic = true, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_be_ssp2_ops, diff --git a/patch/u-boot/u-boot-rockchip/i2c_eeprom_add_read_and_write_functions.patch b/patch/u-boot/u-boot-rockchip/i2c_eeprom_add_read_and_write_functions.patch deleted file mode 100644 index d1d3f69f0..000000000 --- a/patch/u-boot/u-boot-rockchip/i2c_eeprom_add_read_and_write_functions.patch +++ /dev/null @@ -1,97 +0,0 @@ -From d593e8671d4a7150cb799ffcb17052bcf055047d Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Sat, 22 Apr 2017 08:57:41 +0000 -Subject: [PATCH] i2c_eeprom: add read and write functions - -Signed-off-by: Jonas Karlman -Reviewed-by: Simon Glass ---- - drivers/misc/i2c_eeprom.c | 32 ++++++++++++++++++++++++++------ - include/i2c_eeprom.h | 24 ++++++++++++++++++++++++ - 2 files changed, 50 insertions(+), 6 deletions(-) - -diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c -index c9f4174..da6e2b0 100644 ---- a/drivers/misc/i2c_eeprom.c -+++ b/drivers/misc/i2c_eeprom.c -@@ -10,21 +10,41 @@ - #include - #include - --static int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, -- int size) -+int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size) -+{ -+ const struct i2c_eeprom_ops *ops = device_get_ops(dev); -+ -+ if (!ops->read) -+ return -ENOSYS; -+ -+ return ops->read(dev, offset, buf, size); -+} -+ -+int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size) -+{ -+ const struct i2c_eeprom_ops *ops = device_get_ops(dev); -+ -+ if (!ops->write) -+ return -ENOSYS; -+ -+ return ops->write(dev, offset, buf, size); -+} -+ -+static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf, -+ int size) - { - return dm_i2c_read(dev, offset, buf, size); - } - --static int i2c_eeprom_write(struct udevice *dev, int offset, -- const uint8_t *buf, int size) -+static int i2c_eeprom_std_write(struct udevice *dev, int offset, -+ const uint8_t *buf, int size) - { - return -ENODEV; - } - - struct i2c_eeprom_ops i2c_eeprom_std_ops = { -- .read = i2c_eeprom_read, -- .write = i2c_eeprom_write, -+ .read = i2c_eeprom_std_read, -+ .write = i2c_eeprom_std_write, - }; - - static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) -diff --git a/include/i2c_eeprom.h b/include/i2c_eeprom.h -index 0452892..bb5c6b1 100644 ---- a/include/i2c_eeprom.h -+++ b/include/i2c_eeprom.h -@@ -20,4 +20,28 @@ struct i2c_eeprom { - unsigned pagewidth; - }; - -+/* -+ * i2c_eeprom_read() - read bytes from an I2C EEPROM chip -+ * -+ * @dev: Chip to read from -+ * @offset: Offset within chip to start reading -+ * @buf: Place to put data -+ * @size: Number of bytes to read -+ * -+ * @return 0 on success, -ve on failure -+ */ -+int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size); -+ -+/* -+ * i2c_eeprom_write() - write bytes to an I2C EEPROM chip -+ * -+ * @dev: Chip to write to -+ * @offset: Offset within chip to start writing -+ * @buf: Buffer containing data to write -+ * @size: Number of bytes to write -+ * -+ * @return 0 on success, -ve on failure -+ */ -+int i2c_eeprom_write(struct udevice *dev, int offset, uint8_t *buf, int size); -+ - #endif diff --git a/patch/u-boot/u-boot-rockchip/set_ethaddr_in_late_init.patch b/patch/u-boot/u-boot-rockchip/set_ethaddr_in_late_init.patch deleted file mode 100644 index 3d2fd9875..000000000 --- a/patch/u-boot/u-boot-rockchip/set_ethaddr_in_late_init.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 244f8753744eefbd7cd1307c0bd8f7b297486211 Mon Sep 17 00:00:00 2001 -From: Jonas Karlman -Date: Sat, 22 Apr 2017 08:57:54 +0000 -Subject: [PATCH] rockchip: tinker: set ethaddr in late init - -Set ethernet mac address in late init for Tinker Board, -prevents getting a random mac address each boot. - -Read mac address from eeprom, first 6 bytes from m24c08@50. -Same as /etc/init.d/rockchip.sh on Tinker OS. - -Signed-off-by: Jonas Karlman -Reviewed-by: Simon Glass ---- - arch/arm/dts/rk3288-tinker.dts | 7 +++++++ - board/rockchip/tinker_rk3288/tinker-rk3288.c | 28 ++++++++++++++++++++++++++++ - configs/tinker-rk3288_defconfig | 3 +++ - 3 files changed, 38 insertions(+) - -diff --git a/arch/arm/dts/rk3288-tinker.dts b/arch/arm/dts/rk3288-tinker.dts -index f1bef94..4efba50 100644 ---- a/arch/arm/dts/rk3288-tinker.dts -+++ b/arch/arm/dts/rk3288-tinker.dts -@@ -67,3 +67,10 @@ - &gpio8 { - u-boot,dm-pre-reloc; - }; -+ -+&i2c2 { -+ m24c08@50 { -+ compatible = "at,24c08", "i2c-eeprom"; -+ reg = <0x50>; -+ }; -+}; -diff --git a/board/rockchip/tinker_rk3288/tinker-rk3288.c b/board/rockchip/tinker_rk3288/tinker-rk3288.c -index 79541a3..c2872e7 100644 ---- a/board/rockchip/tinker_rk3288/tinker-rk3288.c -+++ b/board/rockchip/tinker_rk3288/tinker-rk3288.c -@@ -5,3 +5,31 @@ - */ - - #include -+#include -+#include -+#include -+ -+static int get_ethaddr_from_eeprom(u8 *addr) -+{ -+ int ret; -+ struct udevice *dev; -+ -+ ret = uclass_first_device_err(UCLASS_I2C_EEPROM, &dev); -+ if (ret) -+ return ret; -+ -+ return i2c_eeprom_read(dev, 0, addr, 6); -+} -+ -+int rk_board_late_init(void) -+{ -+ u8 ethaddr[6]; -+ -+ if (get_ethaddr_from_eeprom(ethaddr)) -+ return 0; -+ -+ if (is_valid_ethaddr(ethaddr)) -+ eth_setenv_enetaddr("ethaddr", ethaddr); -+ -+ return 0; -+} -diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig -index 6e98480..0530121 100644 ---- a/configs/tinker-rk3288_defconfig -+++ b/configs/tinker-rk3288_defconfig -@@ -11,6 +11,7 @@ CONFIG_CONSOLE_MUX=y - # CONFIG_DISPLAY_CPUINFO is not set - CONFIG_SPL_STACK_R=y - CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 -+CONFIG_SPL_I2C_SUPPORT=y - # CONFIG_CMD_IMLS is not set - CONFIG_CMD_GPT=y - CONFIG_CMD_MMC=y -@@ -39,6 +40,8 @@ CONFIG_CLK=y - CONFIG_SPL_CLK=y - CONFIG_ROCKCHIP_GPIO=y - CONFIG_SYS_I2C_ROCKCHIP=y -+CONFIG_MISC=y -+CONFIG_I2C_EEPROM=y - CONFIG_MMC_DW=y - CONFIG_MMC_DW_ROCKCHIP=y - CONFIG_DM_ETH=y