mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 52
|
||||
SUBLEVEL = 53
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
/* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
|
||||
* The page copy blockops can use 0x6000000 to 0x8000000.
|
||||
* The TSB is mapped in the 0x8000000 to 0xa000000 range.
|
||||
* The 8K TSB is mapped in the 0x8000000 to 0x8400000 range.
|
||||
* The 4M TSB is mapped in the 0x8400000 to 0x8800000 range.
|
||||
* The PROM resides in an area spanning 0xf0000000 to 0x100000000.
|
||||
* The vmalloc area spans 0x100000000 to 0x200000000.
|
||||
* Since modules need to be in the lowest 32-bits of the address space,
|
||||
@@ -33,7 +34,8 @@
|
||||
* 0x400000000.
|
||||
*/
|
||||
#define TLBTEMP_BASE _AC(0x0000000006000000,UL)
|
||||
#define TSBMAP_BASE _AC(0x0000000008000000,UL)
|
||||
#define TSBMAP_8K_BASE _AC(0x0000000008000000,UL)
|
||||
#define TSBMAP_4M_BASE _AC(0x0000000008400000,UL)
|
||||
#define MODULES_VADDR _AC(0x0000000010000000,UL)
|
||||
#define MODULES_LEN _AC(0x00000000e0000000,UL)
|
||||
#define MODULES_END _AC(0x00000000f0000000,UL)
|
||||
|
||||
@@ -35,6 +35,8 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
|
||||
{
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
|
||||
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
|
||||
|
||||
extern void flush_tlb_pending(void);
|
||||
@@ -49,11 +51,6 @@ extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
#define flush_tlb_kernel_range(start,end) \
|
||||
do { flush_tsb_kernel_range(start,end); \
|
||||
__flush_tlb_kernel_range(start,end); \
|
||||
} while (0)
|
||||
|
||||
static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
|
||||
{
|
||||
__flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
|
||||
@@ -64,11 +61,6 @@ static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vad
|
||||
extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
|
||||
|
||||
#define flush_tlb_kernel_range(start, end) \
|
||||
do { flush_tsb_kernel_range(start,end); \
|
||||
smp_flush_tlb_kernel_range(start, end); \
|
||||
} while (0)
|
||||
|
||||
#define global_flush_tlb_page(mm, vaddr) \
|
||||
smp_flush_tlb_page(mm, vaddr)
|
||||
|
||||
|
||||
@@ -1336,7 +1336,7 @@ int ldc_connect(struct ldc_channel *lp)
|
||||
if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) ||
|
||||
!(lp->flags & LDC_FLAG_REGISTERED_QUEUES) ||
|
||||
lp->hs_state != LDC_HS_OPEN)
|
||||
err = -EINVAL;
|
||||
err = ((lp->hs_state > LDC_HS_OPEN) ? 0 : -EINVAL);
|
||||
else
|
||||
err = start_handshake(lp);
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ void cpu_panic(void)
|
||||
#define NUM_ROUNDS 64 /* magic value */
|
||||
#define NUM_ITERS 5 /* likewise */
|
||||
|
||||
static DEFINE_SPINLOCK(itc_sync_lock);
|
||||
static DEFINE_RAW_SPINLOCK(itc_sync_lock);
|
||||
static unsigned long go[SLAVE + 1];
|
||||
|
||||
#define DEBUG_TICK_SYNC 0
|
||||
@@ -258,7 +258,7 @@ static void smp_synchronize_one_tick(int cpu)
|
||||
go[MASTER] = 0;
|
||||
membar_safe("#StoreLoad");
|
||||
|
||||
spin_lock_irqsave(&itc_sync_lock, flags);
|
||||
raw_spin_lock_irqsave(&itc_sync_lock, flags);
|
||||
{
|
||||
for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
|
||||
while (!go[MASTER])
|
||||
@@ -269,7 +269,7 @@ static void smp_synchronize_one_tick(int cpu)
|
||||
membar_safe("#StoreLoad");
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&itc_sync_lock, flags);
|
||||
raw_spin_unlock_irqrestore(&itc_sync_lock, flags);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
|
||||
|
||||
@@ -44,7 +44,7 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
|
||||
SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
|
||||
SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
|
||||
SIGN1(sys32_select, compat_sys_select, %o0)
|
||||
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
|
||||
SIGN1(sys32_futex, compat_sys_futex, %o1)
|
||||
SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
|
||||
SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
|
||||
SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
|
||||
|
||||
@@ -163,17 +163,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
|
||||
unsigned long compute_effective_address(struct pt_regs *regs,
|
||||
unsigned int insn, unsigned int rd)
|
||||
{
|
||||
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
|
||||
unsigned int rs1 = (insn >> 14) & 0x1f;
|
||||
unsigned int rs2 = insn & 0x1f;
|
||||
int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
|
||||
unsigned long addr;
|
||||
|
||||
if (insn & 0x2000) {
|
||||
maybe_flush_windows(rs1, 0, rd, from_kernel);
|
||||
return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
|
||||
addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
|
||||
} else {
|
||||
maybe_flush_windows(rs1, rs2, rd, from_kernel);
|
||||
return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
|
||||
addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
|
||||
}
|
||||
|
||||
if (!from_kernel && test_thread_flag(TIF_32BIT))
|
||||
addr &= 0xffffffff;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* This is just to make gcc think die_if_kernel does return... */
|
||||
|
||||
@@ -236,6 +236,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
|
||||
*/
|
||||
VISEntryHalf
|
||||
|
||||
membar #Sync
|
||||
alignaddr %o1, %g0, %g0
|
||||
|
||||
add %o1, (64 - 1), %o4
|
||||
|
||||
@@ -499,7 +499,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs)
|
||||
case 0: fsr = *pfsr;
|
||||
if (IR == -1) IR = 2;
|
||||
/* fcc is always fcc0 */
|
||||
fsr &= ~0xc00; fsr |= (IR << 10); break;
|
||||
fsr &= ~0xc00; fsr |= (IR << 10);
|
||||
*pfsr = fsr;
|
||||
break;
|
||||
case 1: rd->s = IR; break;
|
||||
|
||||
@@ -95,38 +95,51 @@ static unsigned int get_user_insn(unsigned long tpc)
|
||||
pte_t *ptep, pte;
|
||||
unsigned long pa;
|
||||
u32 insn = 0;
|
||||
unsigned long pstate;
|
||||
|
||||
if (pgd_none(*pgdp))
|
||||
goto outret;
|
||||
if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp)))
|
||||
goto out;
|
||||
pudp = pud_offset(pgdp, tpc);
|
||||
if (pud_none(*pudp))
|
||||
goto outret;
|
||||
pmdp = pmd_offset(pudp, tpc);
|
||||
if (pmd_none(*pmdp))
|
||||
goto outret;
|
||||
|
||||
/* This disables preemption for us as well. */
|
||||
__asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
|
||||
__asm__ __volatile__("wrpr %0, %1, %%pstate"
|
||||
: : "r" (pstate), "i" (PSTATE_IE));
|
||||
ptep = pte_offset_map(pmdp, tpc);
|
||||
pte = *ptep;
|
||||
if (!pte_present(pte))
|
||||
if (pud_none(*pudp) || unlikely(pud_bad(*pudp)))
|
||||
goto out;
|
||||
|
||||
pa = (pte_pfn(pte) << PAGE_SHIFT);
|
||||
pa += (tpc & ~PAGE_MASK);
|
||||
/* This disables preemption for us as well. */
|
||||
local_irq_disable();
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
pmdp = pmd_offset(pudp, tpc);
|
||||
if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp)))
|
||||
goto out_irq_enable;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (pmd_trans_huge(*pmdp)) {
|
||||
if (pmd_trans_splitting(*pmdp))
|
||||
goto out_irq_enable;
|
||||
|
||||
pa = pmd_pfn(*pmdp) << PAGE_SHIFT;
|
||||
pa += tpc & ~HPAGE_MASK;
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ptep = pte_offset_map(pmdp, tpc);
|
||||
pte = *ptep;
|
||||
if (pte_present(pte)) {
|
||||
pa = (pte_pfn(pte) << PAGE_SHIFT);
|
||||
pa += (tpc & ~PAGE_MASK);
|
||||
|
||||
/* Use phys bypass so we don't pollute dtlb/dcache. */
|
||||
__asm__ __volatile__("lduwa [%1] %2, %0"
|
||||
: "=r" (insn)
|
||||
: "r" (pa), "i" (ASI_PHYS_USE_EC));
|
||||
}
|
||||
pte_unmap(ptep);
|
||||
}
|
||||
out_irq_enable:
|
||||
local_irq_enable();
|
||||
out:
|
||||
pte_unmap(ptep);
|
||||
__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
|
||||
outret:
|
||||
return insn;
|
||||
}
|
||||
|
||||
@@ -152,7 +165,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
|
||||
}
|
||||
|
||||
static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
|
||||
unsigned int insn, int fault_code)
|
||||
unsigned long fault_addr, unsigned int insn,
|
||||
int fault_code)
|
||||
{
|
||||
unsigned long addr;
|
||||
siginfo_t info;
|
||||
@@ -160,10 +174,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
|
||||
info.si_code = code;
|
||||
info.si_signo = sig;
|
||||
info.si_errno = 0;
|
||||
if (fault_code & FAULT_CODE_ITLB)
|
||||
if (fault_code & FAULT_CODE_ITLB) {
|
||||
addr = regs->tpc;
|
||||
else
|
||||
addr = compute_effective_address(regs, insn, 0);
|
||||
} else {
|
||||
/* If we were able to probe the faulting instruction, use it
|
||||
* to compute a precise fault address. Otherwise use the fault
|
||||
* time provided address which may only have page granularity.
|
||||
*/
|
||||
if (insn)
|
||||
addr = compute_effective_address(regs, insn, 0);
|
||||
else
|
||||
addr = fault_addr;
|
||||
}
|
||||
info.si_addr = (void __user *) addr;
|
||||
info.si_trapno = 0;
|
||||
|
||||
@@ -238,7 +260,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code,
|
||||
/* The si_code was set to make clear whether
|
||||
* this was a SEGV_MAPERR or SEGV_ACCERR fault.
|
||||
*/
|
||||
do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
|
||||
do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -258,18 +280,6 @@ static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
|
||||
show_regs(regs);
|
||||
}
|
||||
|
||||
static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
|
||||
unsigned long addr)
|
||||
{
|
||||
static int times;
|
||||
|
||||
if (times++ < 10)
|
||||
printk(KERN_ERR "FAULT[%s:%d]: 32-bit process "
|
||||
"reports 64-bit fault address [%lx]\n",
|
||||
current->comm, current->pid, addr);
|
||||
show_regs(regs);
|
||||
}
|
||||
|
||||
asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
@@ -298,10 +308,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
||||
goto intr_or_no_mm;
|
||||
}
|
||||
}
|
||||
if (unlikely((address >> 32) != 0)) {
|
||||
bogus_32bit_fault_address(regs, address);
|
||||
if (unlikely((address >> 32) != 0))
|
||||
goto intr_or_no_mm;
|
||||
}
|
||||
}
|
||||
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
@@ -519,7 +527,7 @@ do_sigbus:
|
||||
* Send a sigbus, regardless of whether we were in kernel
|
||||
* or user mode.
|
||||
*/
|
||||
do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
|
||||
do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
if (regs->tstate & TSTATE_PRIV)
|
||||
|
||||
@@ -350,6 +350,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
|
||||
|
||||
mm = vma->vm_mm;
|
||||
|
||||
/* Don't insert a non-valid PTE into the TSB, we'll deadlock. */
|
||||
if (!pte_accessible(mm, pte))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
|
||||
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
|
||||
@@ -2764,3 +2768,26 @@ void hugetlb_setup(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range
|
||||
#else
|
||||
#define do_flush_tlb_kernel_range __flush_tlb_kernel_range
|
||||
#endif
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
if (start < HI_OBP_ADDRESS && end > LOW_OBP_ADDRESS) {
|
||||
if (start < LOW_OBP_ADDRESS) {
|
||||
flush_tsb_kernel_range(start, LOW_OBP_ADDRESS);
|
||||
do_flush_tlb_kernel_range(start, LOW_OBP_ADDRESS);
|
||||
}
|
||||
if (end > HI_OBP_ADDRESS) {
|
||||
flush_tsb_kernel_range(end, HI_OBP_ADDRESS);
|
||||
do_flush_tlb_kernel_range(end, HI_OBP_ADDRESS);
|
||||
}
|
||||
} else {
|
||||
flush_tsb_kernel_range(start, end);
|
||||
do_flush_tlb_kernel_range(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,19 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign
|
||||
mm->context.tsb_block[tsb_idx].tsb_nentries =
|
||||
tsb_bytes / sizeof(struct tsb);
|
||||
|
||||
base = TSBMAP_BASE;
|
||||
switch (tsb_idx) {
|
||||
case MM_TSB_BASE:
|
||||
base = TSBMAP_8K_BASE;
|
||||
break;
|
||||
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
|
||||
case MM_TSB_HUGE:
|
||||
base = TSBMAP_4M_BASE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
tte = pgprot_val(PAGE_KERNEL_LOCKED);
|
||||
tsb_paddr = __pa(mm->context.tsb_block[tsb_idx].tsb);
|
||||
BUG_ON(tsb_paddr & (tsb_bytes - 1UL));
|
||||
|
||||
@@ -312,6 +312,7 @@ struct sw_tx_bd {
|
||||
u8 flags;
|
||||
/* Set on the first BD descriptor when there is a split BD */
|
||||
#define BNX2X_TSO_SPLIT_BD (1<<0)
|
||||
#define BNX2X_HAS_SECOND_PBD (1<<1)
|
||||
};
|
||||
|
||||
struct sw_rx_page {
|
||||
|
||||
@@ -180,6 +180,12 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
|
||||
--nbd;
|
||||
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
|
||||
|
||||
if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) {
|
||||
/* Skip second parse bd... */
|
||||
--nbd;
|
||||
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
|
||||
}
|
||||
|
||||
/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
|
||||
if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
|
||||
tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
|
||||
@@ -3755,6 +3761,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
/* set encapsulation flag in start BD */
|
||||
SET_FLAG(tx_start_bd->general_data,
|
||||
ETH_TX_START_BD_TUNNEL_EXIST, 1);
|
||||
|
||||
tx_buf->flags |= BNX2X_HAS_SECOND_PBD;
|
||||
|
||||
nbd++;
|
||||
} else if (xmit_type & XMIT_CSUM) {
|
||||
/* Set PBD in checksum offload case w/o encapsulation */
|
||||
|
||||
@@ -500,6 +500,7 @@ static int macvlan_init(struct net_device *dev)
|
||||
(lowerdev->state & MACVLAN_STATE_MASK);
|
||||
dev->features = lowerdev->features & MACVLAN_FEATURES;
|
||||
dev->features |= NETIF_F_LLTX;
|
||||
dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
|
||||
dev->gso_max_size = lowerdev->gso_max_size;
|
||||
dev->iflink = lowerdev->ifindex;
|
||||
dev->hard_header_len = lowerdev->hard_header_len;
|
||||
|
||||
@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
||||
nf_reset(skb);
|
||||
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
ip_select_ident(skb, &rt->dst, NULL);
|
||||
ip_select_ident(skb, NULL);
|
||||
ip_send_check(iph);
|
||||
|
||||
ip_local_out(skb);
|
||||
|
||||
@@ -1093,7 +1093,7 @@ static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
iph->daddr = dst;
|
||||
iph->saddr = fl4.saddr;
|
||||
iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
|
||||
__ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
|
||||
__ip_select_ident(iph, skb_shinfo(skb)->gso_segs ?: 1);
|
||||
|
||||
nf_reset(skb);
|
||||
|
||||
|
||||
@@ -452,6 +452,9 @@ static void attach_one_temp(struct bbc_i2c_bus *bp, struct platform_device *op,
|
||||
if (!tp)
|
||||
return;
|
||||
|
||||
INIT_LIST_HEAD(&tp->bp_list);
|
||||
INIT_LIST_HEAD(&tp->glob_list);
|
||||
|
||||
tp->client = bbc_i2c_attach(bp, op);
|
||||
if (!tp->client) {
|
||||
kfree(tp);
|
||||
@@ -497,6 +500,9 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct platform_device *op,
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
INIT_LIST_HEAD(&fp->bp_list);
|
||||
INIT_LIST_HEAD(&fp->glob_list);
|
||||
|
||||
fp->client = bbc_i2c_attach(bp, op);
|
||||
if (!fp->client) {
|
||||
kfree(fp);
|
||||
|
||||
@@ -301,13 +301,18 @@ static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index
|
||||
if (!bp)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&bp->temps);
|
||||
INIT_LIST_HEAD(&bp->fans);
|
||||
|
||||
bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs");
|
||||
if (!bp->i2c_control_regs)
|
||||
goto fail;
|
||||
|
||||
bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
|
||||
if (!bp->i2c_bussel_reg)
|
||||
goto fail;
|
||||
if (op->num_resources == 2) {
|
||||
bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
|
||||
if (!bp->i2c_bussel_reg)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bp->waiting = 0;
|
||||
init_waitqueue_head(&bp->wq);
|
||||
|
||||
@@ -157,6 +157,15 @@ receive_chars(struct uart_sunsab_port *up,
|
||||
(up->port.line == up->port.cons->index))
|
||||
saw_console_brk = 1;
|
||||
|
||||
if (count == 0) {
|
||||
if (unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
|
||||
stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
|
||||
SAB82532_ISR0_FERR);
|
||||
up->port.icount.brk++;
|
||||
uart_handle_break(&up->port);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned char ch = buf[i], flag;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user