You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge 5.10.44 into android12-5.10-lts
Changes in 5.10.44 proc: Track /proc/$pid/attr/ opener mm_struct ASoC: max98088: fix ni clock divider calculation ASoC: amd: fix for pcm_read() error spi: Fix spi device unregister flow spi: spi-zynq-qspi: Fix stack violation bug bpf: Forbid trampoline attach for functions with variable arguments net/nfc/rawsock.c: fix a permission check bug usb: cdns3: Fix runtime PM imbalance on error ASoC: Intel: bytcr_rt5640: Add quirk for the Glavey TM800A550L tablet ASoC: Intel: bytcr_rt5640: Add quirk for the Lenovo Miix 3-830 tablet vfio-ccw: Reset FSM state to IDLE inside FSM vfio-ccw: Serialize FSM IDLE state with I/O completion ASoC: sti-sas: add missing MODULE_DEVICE_TABLE spi: sprd: Add missing MODULE_DEVICE_TABLE usb: chipidea: udc: assign interrupt number to USB gadget structure isdn: mISDN: netjet: Fix crash in nj_probe: bonding: init notify_work earlier to avoid uninitialized use netlink: disable IRQs for netlink_lock_table() net: mdiobus: get rid of a BUG_ON() cgroup: disable controllers at parse time wq: handle VM suspension in stall detection net/qla3xxx: fix schedule while atomic in ql_sem_spinlock RDS tcp loopback connection can hang net:sfc: fix non-freed irq in legacy irq mode scsi: bnx2fc: Return failure if io_req is already in ABTS processing scsi: vmw_pvscsi: Set correct residual data length scsi: hisi_sas: Drop free_irq() of devm_request_irq() allocated irq scsi: target: qla2xxx: Wait for stop_phase1 at WWN removal net: macb: ensure the device is available before accessing GEMGXL control registers net: appletalk: cops: Fix data race in cops_probe1 net: dsa: microchip: enable phy errata workaround on 9567 nvme-fabrics: decode host pathing error for connect MIPS: Fix kernel hang under FUNCTION_GRAPH_TRACER and PREEMPT_TRACER dm verity: fix require_signatures module_param permissions bnx2x: Fix missing error code in bnx2x_iov_init_one() nvme-tcp: remove incorrect Kconfig dep in BLK_DEV_NVME nvmet: fix false keep-alive timeout when a controller is torn down powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P2041 i2c controllers powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P1010 i2c controllers spi: Don't have controller clean up spi device before driver unbind spi: Cleanup on failure of initial setup i2c: mpc: Make use of i2c_recover_bus() i2c: mpc: implement erratum A-004447 workaround ALSA: seq: Fix race of snd_seq_timer_open() ALSA: firewire-lib: fix the context to call snd_pcm_stop_xrun() ALSA: hda/realtek: headphone and mic don't work on an Acer laptop ALSA: hda/realtek: fix mute/micmute LEDs and speaker for HP Elite Dragonfly G2 ALSA: hda/realtek: fix mute/micmute LEDs and speaker for HP EliteBook x360 1040 G8 ALSA: hda/realtek: fix mute/micmute LEDs for HP EliteBook 840 Aero G8 ALSA: hda/realtek: fix mute/micmute LEDs for HP ZBook Power G8 spi: bcm2835: Fix out-of-bounds access with more than 4 slaves Revert "ACPI: sleep: Put the FACS table after using it" drm: Fix use-after-free read in drm_getunique() drm: Lock pointer access in drm_master_release() perf/x86/intel/uncore: Fix M2M event umask for Ice Lake server KVM: X86: MMU: Use the correct inherited permissions to get shadow page kvm: avoid speculation-based attacks from out-of-range memslot accesses staging: rtl8723bs: Fix uninitialized variables async_xor: check src_offs is not NULL before updating it btrfs: return value from btrfs_mark_extent_written() in case of error btrfs: promote debugging asserts to full-fledged checks in validate_super cgroup1: don't allow '\n' in renaming ftrace: Do not blindly read the ip address in ftrace_bug() mmc: renesas_sdhi: abort tuning when timeout detected mmc: renesas_sdhi: Fix HS400 on R-Car M3-W+ USB: f_ncm: ncm_bitrate (speed) is unsigned usb: f_ncm: only first packet of aggregate needs to start timer usb: pd: Set PD_T_SINK_WAIT_CAP to 310ms usb: dwc3-meson-g12a: fix usb2 PHY glue init when phy0 is disabled usb: dwc3: meson-g12a: Disable the regulator in the error handling path of the probe usb: dwc3: gadget: Bail from dwc3_gadget_exit() if dwc->gadget is NULL usb: dwc3: ep0: fix NULL pointer exception usb: musb: fix MUSB_QUIRK_B_DISCONNECT_99 handling usb: typec: wcove: Use LE to CPU conversion when accessing msg->header usb: typec: ucsi: Clear PPM capability data in ucsi_init() error path usb: typec: intel_pmc_mux: Put fwnode in error case during ->probe() usb: typec: intel_pmc_mux: Add missed error check for devm_ioremap_resource() usb: gadget: f_fs: Ensure io_completion_wq is idle during unbind USB: serial: ftdi_sio: add NovaTech OrionMX product ID USB: serial: omninet: add device id for Zyxel Omni 56K Plus USB: serial: quatech2: fix control-request directions USB: serial: cp210x: fix alternate function for CP2102N QFN20 usb: gadget: eem: fix wrong eem header operation usb: fix various gadgets null ptr deref on 10gbps cabling. usb: fix various gadget panics on 10gbps cabling usb: typec: tcpm: cancel vdm and state machine hrtimer when unregister tcpm port usb: typec: tcpm: cancel frs hrtimer when unregister tcpm port regulator: core: resolve supply for boot-on/always-on regulators regulator: max77620: Use device_set_of_node_from_dev() regulator: bd718x7: Fix the BUCK7 voltage setting on BD71837 regulator: fan53880: Fix missing n_voltages setting regulator: bd71828: Fix .n_voltages settings regulator: rtmv20: Fix .set_current_limit/.get_current_limit callbacks phy: usb: Fix misuse of IS_ENABLED usb: dwc3: gadget: Disable gadget IRQ during pullup disable usb: typec: mux: Fix copy-paste mistake in typec_mux_match drm/mcde: Fix off by 10^3 in calculation drm/msm/a6xx: fix incorrectly set uavflagprd_inv field for A650 drm/msm/a6xx: update/fix CP_PROTECT initialization drm/msm/a6xx: avoid shadow NULL reference in failure path RDMA/ipoib: Fix warning caused by destroying non-initial netns RDMA/mlx4: Do not map the core_clock page to user space unless enabled ARM: cpuidle: Avoid orphan section warning vmlinux.lds.h: Avoid orphan section with !SMP tools/bootconfig: Fix error return code in apply_xbc() phy: cadence: Sierra: Fix error return code in cdns_sierra_phy_probe() ASoC: core: Fix Null-point-dereference in fmt_single_name() ASoC: meson: gx-card: fix sound-dai dt schema phy: ti: Fix an error code in wiz_probe() gpio: wcd934x: Fix shift-out-of-bounds error perf: Fix data race between pin_count increment/decrement sched/fair: Keep load_avg and load_sum synced sched/fair: Make sure to update tg contrib for blocked load sched/fair: Fix util_est UTIL_AVG_UNCHANGED handling x86/nmi_watchdog: Fix old-style NMI watchdog regression on old Intel CPUs KVM: x86: Ensure liveliness of nested VM-Enter fail tracepoint message IB/mlx5: Fix initializing CQ fragments buffer NFS: Fix a potential NULL dereference in nfs_get_client() NFSv4: Fix deadlock between nfs4_evict_inode() and nfs4_opendata_get_inode() perf session: Correct buffer copying when peeking events kvm: fix previous commit for 32-bit builds NFS: Fix use-after-free in nfs4_init_client() NFSv4: Fix second deadlock in nfs4_evict_inode() NFSv4: nfs4_proc_set_acl needs to restore NFS_CAP_UIDGID_NOMAP on error. scsi: core: Fix error handling of scsi_host_alloc() scsi: core: Fix failure handling of scsi_add_host_with_dma() scsi: core: Put .shost_dev in failure path if host state changes to RUNNING scsi: core: Only put parent device if host state differs from SHOST_CREATED tracing: Correct the length check which causes memory corruption proc: only require mm_struct for writing Linux 5.10.44 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ic64172b4e72ccb54d96000b3065dd8b33aa9fef5
This commit is contained in:
@@ -57,7 +57,7 @@ patternProperties:
|
||||
rate
|
||||
|
||||
sound-dai:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: phandle of the CPU DAI
|
||||
|
||||
patternProperties:
|
||||
@@ -71,7 +71,7 @@ patternProperties:
|
||||
|
||||
properties:
|
||||
sound-dai:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: phandle of the codec DAI
|
||||
|
||||
required:
|
||||
|
||||
@@ -171,8 +171,8 @@ Shadow pages contain the following information:
|
||||
shadow pages) so role.quadrant takes values in the range 0..3. Each
|
||||
quadrant maps 1GB virtual address space.
|
||||
role.access:
|
||||
Inherited guest access permissions in the form uwx. Note execute
|
||||
permission is positive, not negative.
|
||||
Inherited guest access permissions from the parent ptes in the form uwx.
|
||||
Note execute permission is positive, not negative.
|
||||
role.invalid:
|
||||
The page is invalid and should not be used. It is a root page that is
|
||||
currently pinned (by a cpu hardware register pointing to it); once it is
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 43
|
||||
SUBLEVEL = 44
|
||||
EXTRAVERSION =
|
||||
NAME = Dare mighty things
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#ifdef CONFIG_CPU_IDLE
|
||||
extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
#define __cpuidle_method_section __used __section("__cpuidle_method_of_table")
|
||||
#else
|
||||
static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index) { return -ENODEV; }
|
||||
#define __cpuidle_method_section __maybe_unused /* drop silently */
|
||||
#endif
|
||||
|
||||
/* Common ARM WFI state */
|
||||
@@ -42,8 +44,7 @@ struct of_cpuidle_method {
|
||||
|
||||
#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \
|
||||
static const struct of_cpuidle_method __cpuidle_method_of_table_##name \
|
||||
__used __section("__cpuidle_method_of_table") \
|
||||
= { .method = _method, .ops = _ops }
|
||||
__cpuidle_method_section = { .method = _method, .ops = _ops }
|
||||
|
||||
extern int arm_cpuidle_suspend(int index);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*/
|
||||
notrace void arch_local_irq_disable(void)
|
||||
{
|
||||
preempt_disable();
|
||||
preempt_disable_notrace();
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -53,7 +53,7 @@ notrace void arch_local_irq_disable(void)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
|
||||
preempt_enable();
|
||||
preempt_enable_notrace();
|
||||
}
|
||||
EXPORT_SYMBOL(arch_local_irq_disable);
|
||||
|
||||
@@ -61,7 +61,7 @@ notrace unsigned long arch_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
preempt_disable();
|
||||
preempt_disable_notrace();
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -78,7 +78,7 @@ notrace unsigned long arch_local_irq_save(void)
|
||||
: /* no inputs */
|
||||
: "memory");
|
||||
|
||||
preempt_enable();
|
||||
preempt_enable_notrace();
|
||||
|
||||
return flags;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ notrace void arch_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
unsigned long __tmp1;
|
||||
|
||||
preempt_disable();
|
||||
preempt_disable_notrace();
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -106,7 +106,7 @@ notrace void arch_local_irq_restore(unsigned long flags)
|
||||
: "0" (flags)
|
||||
: "memory");
|
||||
|
||||
preempt_enable();
|
||||
preempt_enable_notrace();
|
||||
}
|
||||
EXPORT_SYMBOL(arch_local_irq_restore);
|
||||
|
||||
|
||||
@@ -122,7 +122,15 @@
|
||||
};
|
||||
|
||||
/include/ "pq3-i2c-0.dtsi"
|
||||
i2c@3000 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
/include/ "pq3-i2c-1.dtsi"
|
||||
i2c@3100 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
/include/ "pq3-duart-0.dtsi"
|
||||
/include/ "pq3-espi-0.dtsi"
|
||||
spi0: spi@7000 {
|
||||
|
||||
@@ -371,7 +371,23 @@
|
||||
};
|
||||
|
||||
/include/ "qoriq-i2c-0.dtsi"
|
||||
i2c@118000 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
i2c@118100 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
/include/ "qoriq-i2c-1.dtsi"
|
||||
i2c@119000 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
i2c@119100 {
|
||||
fsl,i2c-erratum-a004447;
|
||||
};
|
||||
|
||||
/include/ "qoriq-duart-0.dtsi"
|
||||
/include/ "qoriq-duart-1.dtsi"
|
||||
/include/ "qoriq-gpio-0.dtsi"
|
||||
|
||||
@@ -5067,9 +5067,10 @@ static struct intel_uncore_type icx_uncore_m2m = {
|
||||
.perf_ctr = SNR_M2M_PCI_PMON_CTR0,
|
||||
.event_ctl = SNR_M2M_PCI_PMON_CTL0,
|
||||
.event_mask = SNBEP_PMON_RAW_EVENT_MASK,
|
||||
.event_mask_ext = SNR_M2M_PCI_PMON_UMASK_EXT,
|
||||
.box_ctl = SNR_M2M_PCI_PMON_BOX_CTL,
|
||||
.ops = &snr_m2m_uncore_pci_ops,
|
||||
.format_group = &skx_uncore_format_group,
|
||||
.format_group = &snr_m2m_uncore_format_group,
|
||||
};
|
||||
|
||||
static struct attribute *icx_upi_uncore_formats_attr[] = {
|
||||
|
||||
@@ -63,7 +63,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
|
||||
case 15:
|
||||
return msr - MSR_P4_BPU_PERFCTR0;
|
||||
}
|
||||
fallthrough;
|
||||
break;
|
||||
case X86_VENDOR_ZHAOXIN:
|
||||
case X86_VENDOR_CENTAUR:
|
||||
return msr - MSR_ARCH_PERFMON_PERFCTR0;
|
||||
@@ -96,7 +96,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
|
||||
case 15:
|
||||
return msr - MSR_P4_BSU_ESCR0;
|
||||
}
|
||||
fallthrough;
|
||||
break;
|
||||
case X86_VENDOR_ZHAOXIN:
|
||||
case X86_VENDOR_CENTAUR:
|
||||
return msr - MSR_ARCH_PERFMON_EVENTSEL0;
|
||||
|
||||
@@ -90,8 +90,8 @@ struct guest_walker {
|
||||
gpa_t pte_gpa[PT_MAX_FULL_LEVELS];
|
||||
pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS];
|
||||
bool pte_writable[PT_MAX_FULL_LEVELS];
|
||||
unsigned pt_access;
|
||||
unsigned pte_access;
|
||||
unsigned int pt_access[PT_MAX_FULL_LEVELS];
|
||||
unsigned int pte_access;
|
||||
gfn_t gfn;
|
||||
struct x86_exception fault;
|
||||
};
|
||||
@@ -418,13 +418,15 @@ retry_walk:
|
||||
}
|
||||
|
||||
walker->ptes[walker->level - 1] = pte;
|
||||
|
||||
/* Convert to ACC_*_MASK flags for struct guest_walker. */
|
||||
walker->pt_access[walker->level - 1] = FNAME(gpte_access)(pt_access ^ walk_nx_mask);
|
||||
} while (!is_last_gpte(mmu, walker->level, pte));
|
||||
|
||||
pte_pkey = FNAME(gpte_pkeys)(vcpu, pte);
|
||||
accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0;
|
||||
|
||||
/* Convert to ACC_*_MASK flags for struct guest_walker. */
|
||||
walker->pt_access = FNAME(gpte_access)(pt_access ^ walk_nx_mask);
|
||||
walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask);
|
||||
errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access);
|
||||
if (unlikely(errcode))
|
||||
@@ -463,7 +465,8 @@ retry_walk:
|
||||
}
|
||||
|
||||
pgprintk("%s: pte %llx pte_access %x pt_access %x\n",
|
||||
__func__, (u64)pte, walker->pte_access, walker->pt_access);
|
||||
__func__, (u64)pte, walker->pte_access,
|
||||
walker->pt_access[walker->level - 1]);
|
||||
return 1;
|
||||
|
||||
error:
|
||||
@@ -635,7 +638,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
|
||||
bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled;
|
||||
struct kvm_mmu_page *sp = NULL;
|
||||
struct kvm_shadow_walk_iterator it;
|
||||
unsigned direct_access, access = gw->pt_access;
|
||||
unsigned int direct_access, access;
|
||||
int top_level, level, req_level, ret;
|
||||
gfn_t base_gfn = gw->gfn;
|
||||
|
||||
@@ -667,6 +670,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
|
||||
sp = NULL;
|
||||
if (!is_shadow_present_pte(*it.sptep)) {
|
||||
table_gfn = gw->table_gfn[it.level - 2];
|
||||
access = gw->pt_access[it.level - 2];
|
||||
sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1,
|
||||
false, access);
|
||||
}
|
||||
|
||||
@@ -1514,16 +1514,16 @@ TRACE_EVENT(kvm_nested_vmenter_failed,
|
||||
TP_ARGS(msg, err),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const char *, msg)
|
||||
__string(msg, msg)
|
||||
__field(u32, err)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->msg = msg;
|
||||
__assign_str(msg, msg);
|
||||
__entry->err = err;
|
||||
),
|
||||
|
||||
TP_printk("%s%s", __entry->msg, !__entry->err ? "" :
|
||||
TP_printk("%s%s", __get_str(msg), !__entry->err ? "" :
|
||||
__print_symbolic(__entry->err, VMX_VMENTER_INSTRUCTION_ERRORS))
|
||||
);
|
||||
|
||||
|
||||
@@ -233,7 +233,8 @@ async_xor_offs(struct page *dest, unsigned int offset,
|
||||
if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
|
||||
src_cnt--;
|
||||
src_list++;
|
||||
src_offs++;
|
||||
if (src_offs)
|
||||
src_offs++;
|
||||
}
|
||||
|
||||
/* wait for any prerequisite operations */
|
||||
|
||||
@@ -1290,10 +1290,8 @@ static void acpi_sleep_hibernate_setup(void)
|
||||
return;
|
||||
|
||||
acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);
|
||||
if (facs) {
|
||||
if (facs)
|
||||
s4_hardware_signature = facs->hardware_signature;
|
||||
acpi_put_table((struct acpi_table_header *)facs);
|
||||
}
|
||||
}
|
||||
#else /* !CONFIG_HIBERNATION */
|
||||
static inline void acpi_sleep_hibernate_setup(void) {}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#define WCD_PIN_MASK(p) BIT(p - 1)
|
||||
#define WCD_PIN_MASK(p) BIT(p)
|
||||
#define WCD_REG_DIR_CTL_OFFSET 0x42
|
||||
#define WCD_REG_VAL_CTL_OFFSET 0x43
|
||||
#define WCD934X_NPINS 5
|
||||
|
||||
@@ -314,9 +314,10 @@ int drm_master_open(struct drm_file *file_priv)
|
||||
void drm_master_release(struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_device *dev = file_priv->minor->dev;
|
||||
struct drm_master *master = file_priv->master;
|
||||
struct drm_master *master;
|
||||
|
||||
mutex_lock(&dev->master_mutex);
|
||||
master = file_priv->master;
|
||||
if (file_priv->magic)
|
||||
idr_remove(&file_priv->master->magic_map, file_priv->magic);
|
||||
|
||||
|
||||
@@ -118,17 +118,18 @@ int drm_getunique(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_unique *u = data;
|
||||
struct drm_master *master = file_priv->master;
|
||||
struct drm_master *master;
|
||||
|
||||
mutex_lock(&master->dev->master_mutex);
|
||||
mutex_lock(&dev->master_mutex);
|
||||
master = file_priv->master;
|
||||
if (u->unique_len >= master->unique_len) {
|
||||
if (copy_to_user(u->unique, master->unique, master->unique_len)) {
|
||||
mutex_unlock(&master->dev->master_mutex);
|
||||
mutex_unlock(&dev->master_mutex);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
u->unique_len = master->unique_len;
|
||||
mutex_unlock(&master->dev->master_mutex);
|
||||
mutex_unlock(&dev->master_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -577,7 +577,7 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d,
|
||||
* porches and sync.
|
||||
*/
|
||||
/* (ps/s) / (pixels/s) = ps/pixels */
|
||||
pclk = DIV_ROUND_UP_ULL(1000000000000, mode->clock);
|
||||
pclk = DIV_ROUND_UP_ULL(1000000000000, (mode->clock * 1000));
|
||||
dev_dbg(d->dev, "picoseconds between two pixels: %llu\n",
|
||||
pclk);
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
* GPU registers so we need to add 0x1a800 to the register value on A630
|
||||
* to get the right value from PM4.
|
||||
*/
|
||||
get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800,
|
||||
get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
|
||||
rbmemptr_stats(ring, index, alwayson_start));
|
||||
|
||||
/* Invalidate CCU depth and color */
|
||||
@@ -184,7 +184,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
|
||||
get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
|
||||
rbmemptr_stats(ring, index, cpcycles_end));
|
||||
get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800,
|
||||
get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
|
||||
rbmemptr_stats(ring, index, alwayson_end));
|
||||
|
||||
/* Write the fence to the scratch register */
|
||||
@@ -203,8 +203,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
OUT_RING(ring, submit->seqno);
|
||||
|
||||
trace_msm_gpu_submit_flush(submit,
|
||||
gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L,
|
||||
REG_A6XX_GMU_ALWAYS_ON_COUNTER_H));
|
||||
gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
|
||||
REG_A6XX_CP_ALWAYS_ON_COUNTER_HI));
|
||||
|
||||
a6xx_flush(gpu, ring);
|
||||
}
|
||||
@@ -459,6 +459,113 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
|
||||
gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
|
||||
}
|
||||
|
||||
/* For a615, a616, a618, A619, a630, a640 and a680 */
|
||||
static const u32 a6xx_protect[] = {
|
||||
A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
|
||||
A6XX_PROTECT_RDONLY(0x00501, 0x0005),
|
||||
A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
|
||||
A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00510, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00534, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00800, 0x0082),
|
||||
A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
|
||||
A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
|
||||
A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
|
||||
A6XX_PROTECT_NORDWR(0x00900, 0x004d),
|
||||
A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
|
||||
A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
|
||||
A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
|
||||
A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
|
||||
A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
|
||||
A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
|
||||
A6XX_PROTECT_NORDWR(0x09624, 0x01db),
|
||||
A6XX_PROTECT_NORDWR(0x09e70, 0x0001),
|
||||
A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
|
||||
A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
|
||||
A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
|
||||
A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
|
||||
A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
|
||||
A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
|
||||
A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */
|
||||
};
|
||||
|
||||
/* These are for a620 and a650 */
|
||||
static const u32 a650_protect[] = {
|
||||
A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
|
||||
A6XX_PROTECT_RDONLY(0x00501, 0x0005),
|
||||
A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
|
||||
A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00510, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00534, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x00800, 0x0082),
|
||||
A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
|
||||
A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
|
||||
A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
|
||||
A6XX_PROTECT_NORDWR(0x00900, 0x004d),
|
||||
A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
|
||||
A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
|
||||
A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
|
||||
A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
|
||||
A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
|
||||
A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
|
||||
A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
|
||||
A6XX_PROTECT_NORDWR(0x09624, 0x01db),
|
||||
A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
|
||||
A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
|
||||
A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
|
||||
A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
|
||||
A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
|
||||
A6XX_PROTECT_NORDWR(0x0b608, 0x0007),
|
||||
A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
|
||||
A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
|
||||
A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
|
||||
A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x1a800, 0x1fff),
|
||||
A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
|
||||
A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
|
||||
A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
|
||||
A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
|
||||
};
|
||||
|
||||
static void a6xx_set_cp_protect(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
const u32 *regs = a6xx_protect;
|
||||
unsigned i, count = ARRAY_SIZE(a6xx_protect), count_max = 32;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48);
|
||||
|
||||
if (adreno_is_a650(adreno_gpu)) {
|
||||
regs = a650_protect;
|
||||
count = ARRAY_SIZE(a650_protect);
|
||||
count_max = 48;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable access protection to privileged registers, fault on an access
|
||||
* protect violation and select the last span to protect from the start
|
||||
* address all the way to the end of the register address space
|
||||
*/
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, BIT(0) | BIT(1) | BIT(3));
|
||||
|
||||
for (i = 0; i < count - 1; i++)
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]);
|
||||
/* last CP_PROTECT to have "infinite" length on the last entry */
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
|
||||
}
|
||||
|
||||
static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
@@ -486,7 +593,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
|
||||
rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1);
|
||||
gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1);
|
||||
gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL,
|
||||
uavflagprd_inv >> 4 | lower_bit << 1);
|
||||
uavflagprd_inv << 4 | lower_bit << 1);
|
||||
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21);
|
||||
}
|
||||
|
||||
@@ -722,41 +829,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
|
||||
}
|
||||
|
||||
/* Protect registers from the CP */
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x00000003);
|
||||
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(0),
|
||||
A6XX_PROTECT_RDONLY(0x600, 0x51));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(1), A6XX_PROTECT_RW(0xae50, 0x2));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(2), A6XX_PROTECT_RW(0x9624, 0x13));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(3), A6XX_PROTECT_RW(0x8630, 0x8));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(4), A6XX_PROTECT_RW(0x9e70, 0x1));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(5), A6XX_PROTECT_RW(0x9e78, 0x187));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(6), A6XX_PROTECT_RW(0xf000, 0x810));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(7),
|
||||
A6XX_PROTECT_RDONLY(0xfc00, 0x3));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(8), A6XX_PROTECT_RW(0x50e, 0x0));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(9), A6XX_PROTECT_RDONLY(0x50f, 0x0));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(10), A6XX_PROTECT_RW(0x510, 0x0));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(11),
|
||||
A6XX_PROTECT_RDONLY(0x0, 0x4f9));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(12),
|
||||
A6XX_PROTECT_RDONLY(0x501, 0xa));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(13),
|
||||
A6XX_PROTECT_RDONLY(0x511, 0x44));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(14), A6XX_PROTECT_RW(0xe00, 0xe));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(15), A6XX_PROTECT_RW(0x8e00, 0x0));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(16), A6XX_PROTECT_RW(0x8e50, 0xf));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(17), A6XX_PROTECT_RW(0xbe02, 0x0));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(18),
|
||||
A6XX_PROTECT_RW(0xbe20, 0x11f3));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(19), A6XX_PROTECT_RW(0x800, 0x82));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(20), A6XX_PROTECT_RW(0x8a0, 0x8));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(21), A6XX_PROTECT_RW(0x8ab, 0x19));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(22), A6XX_PROTECT_RW(0x900, 0x4d));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(23), A6XX_PROTECT_RW(0x98d, 0x76));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(24),
|
||||
A6XX_PROTECT_RDONLY(0x980, 0x4));
|
||||
gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0));
|
||||
a6xx_set_cp_protect(gpu);
|
||||
|
||||
/* Enable expanded apriv for targets that support it */
|
||||
if (gpu->hw_apriv) {
|
||||
@@ -1055,7 +1128,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami)
|
||||
if (a6xx_gpu->shadow_bo)
|
||||
for (i = 0; i < gpu->nr_rings; i++)
|
||||
a6xx_gpu->shadow[i] = 0;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ struct a6xx_gpu {
|
||||
* REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len
|
||||
* registers starting at _reg.
|
||||
*/
|
||||
#define A6XX_PROTECT_RW(_reg, _len) \
|
||||
#define A6XX_PROTECT_NORDWR(_reg, _len) \
|
||||
((1 << 31) | \
|
||||
(((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF))
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -49,6 +50,7 @@
|
||||
#define CCR_MTX 0x10
|
||||
#define CCR_TXAK 0x08
|
||||
#define CCR_RSTA 0x04
|
||||
#define CCR_RSVD 0x02
|
||||
|
||||
#define CSR_MCF 0x80
|
||||
#define CSR_MAAS 0x40
|
||||
@@ -70,6 +72,7 @@ struct mpc_i2c {
|
||||
u8 fdr, dfsrr;
|
||||
#endif
|
||||
struct clk *clk_per;
|
||||
bool has_errata_A004447;
|
||||
};
|
||||
|
||||
struct mpc_i2c_divider {
|
||||
@@ -176,6 +179,75 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask)
|
||||
{
|
||||
void __iomem *addr = i2c->base + MPC_I2C_SR;
|
||||
u8 val;
|
||||
|
||||
return readb_poll_timeout(addr, val, val & mask, 0, 100);
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for Erratum A004447. From the P2040CE Rev Q
|
||||
*
|
||||
* 1. Set up the frequency divider and sampling rate.
|
||||
* 2. I2CCR - a0h
|
||||
* 3. Poll for I2CSR[MBB] to get set.
|
||||
* 4. If I2CSR[MAL] is set (an indication that SDA is stuck low), then go to
|
||||
* step 5. If MAL is not set, then go to step 13.
|
||||
* 5. I2CCR - 00h
|
||||
* 6. I2CCR - 22h
|
||||
* 7. I2CCR - a2h
|
||||
* 8. Poll for I2CSR[MBB] to get set.
|
||||
* 9. Issue read to I2CDR.
|
||||
* 10. Poll for I2CSR[MIF] to be set.
|
||||
* 11. I2CCR - 82h
|
||||
* 12. Workaround complete. Skip the next steps.
|
||||
* 13. Issue read to I2CDR.
|
||||
* 14. Poll for I2CSR[MIF] to be set.
|
||||
* 15. I2CCR - 80h
|
||||
*/
|
||||
static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
writeccr(i2c, CCR_MEN | CCR_MSTA);
|
||||
ret = i2c_mpc_wait_sr(i2c, CSR_MBB);
|
||||
if (ret) {
|
||||
dev_err(i2c->dev, "timeout waiting for CSR_MBB\n");
|
||||
return;
|
||||
}
|
||||
|
||||
val = readb(i2c->base + MPC_I2C_SR);
|
||||
|
||||
if (val & CSR_MAL) {
|
||||
writeccr(i2c, 0x00);
|
||||
writeccr(i2c, CCR_MSTA | CCR_RSVD);
|
||||
writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD);
|
||||
ret = i2c_mpc_wait_sr(i2c, CSR_MBB);
|
||||
if (ret) {
|
||||
dev_err(i2c->dev, "timeout waiting for CSR_MBB\n");
|
||||
return;
|
||||
}
|
||||
val = readb(i2c->base + MPC_I2C_DR);
|
||||
ret = i2c_mpc_wait_sr(i2c, CSR_MIF);
|
||||
if (ret) {
|
||||
dev_err(i2c->dev, "timeout waiting for CSR_MIF\n");
|
||||
return;
|
||||
}
|
||||
writeccr(i2c, CCR_MEN | CCR_RSVD);
|
||||
} else {
|
||||
val = readb(i2c->base + MPC_I2C_DR);
|
||||
ret = i2c_mpc_wait_sr(i2c, CSR_MIF);
|
||||
if (ret) {
|
||||
dev_err(i2c->dev, "timeout waiting for CSR_MIF\n");
|
||||
return;
|
||||
}
|
||||
writeccr(i2c, CCR_MEN);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
|
||||
static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
|
||||
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
|
||||
@@ -586,7 +658,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
|
||||
writeb(status & ~CSR_MAL,
|
||||
i2c->base + MPC_I2C_SR);
|
||||
mpc_i2c_fixup(i2c);
|
||||
i2c_recover_bus(&i2c->adap);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -622,7 +694,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
|
||||
writeb(status & ~CSR_MAL,
|
||||
i2c->base + MPC_I2C_SR);
|
||||
mpc_i2c_fixup(i2c);
|
||||
i2c_recover_bus(&i2c->adap);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -637,6 +709,18 @@ static u32 mpc_functionality(struct i2c_adapter *adap)
|
||||
| I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
|
||||
}
|
||||
|
||||
static int fsl_i2c_bus_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
struct mpc_i2c *i2c = i2c_get_adapdata(adap);
|
||||
|
||||
if (i2c->has_errata_A004447)
|
||||
mpc_i2c_fixup_A004447(i2c);
|
||||
else
|
||||
mpc_i2c_fixup(i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm mpc_algo = {
|
||||
.master_xfer = mpc_xfer,
|
||||
.functionality = mpc_functionality,
|
||||
@@ -648,6 +732,10 @@ static struct i2c_adapter mpc_ops = {
|
||||
.timeout = HZ,
|
||||
};
|
||||
|
||||
static struct i2c_bus_recovery_info fsl_i2c_recovery_info = {
|
||||
.recover_bus = fsl_i2c_bus_recovery,
|
||||
};
|
||||
|
||||
static const struct of_device_id mpc_i2c_of_match[];
|
||||
static int fsl_i2c_probe(struct platform_device *op)
|
||||
{
|
||||
@@ -732,6 +820,8 @@ static int fsl_i2c_probe(struct platform_device *op)
|
||||
dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
|
||||
|
||||
platform_set_drvdata(op, i2c);
|
||||
if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447"))
|
||||
i2c->has_errata_A004447 = true;
|
||||
|
||||
i2c->adap = mpc_ops;
|
||||
of_address_to_resource(op->dev.of_node, 0, &res);
|
||||
@@ -740,6 +830,7 @@ static int fsl_i2c_probe(struct platform_device *op)
|
||||
i2c_set_adapdata(&i2c->adap, i2c);
|
||||
i2c->adap.dev.parent = &op->dev;
|
||||
i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
|
||||
i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info;
|
||||
|
||||
result = i2c_add_adapter(&i2c->adap);
|
||||
if (result < 0)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user