mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS fixes from Ralf Baechle: "This is the first round of fixes and tying up loose ends for MIPS. - plenty of fixes for build errors in specific obscure configurations - remove redundant code on the Lantiq platform - removal of a useless SEAD I2C driver that was causing a build issue - fix an earlier TLB exeption handler fix to also work on Octeon. - fix ISA level dependencies in FPU emulator's instruction decoding. - don't hardcode kernel command line in Octeon software emulator. - fix an earlier fix for the Loondson 2 clock setting" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: MIPS: SEAD3: Fix I2C device registration. MIPS: SEAD3: Nuke PIC32 I2C driver. MIPS: ftrace: Fix a microMIPS build problem MIPS: MSP71xx: Fix build error MIPS: Malta: Do not build the malta-amon.c file if CMP is not enabled MIPS: Prevent compiler warning from cop2_{save,restore} MIPS: Kconfig: Add missing MIPS_CPS dependencies to PM and cpuidle MIPS: idle: Remove leftover __pastwait symbol and its references MIPS: Sibyte: Include the swarm subdir to the sb1250 LittleSur builds MIPS: ptrace.h: Add a missing include MIPS: ath79: Fix compilation error when CONFIG_PCI is disabled MIPS: MSP71xx: Remove compilation error when CONFIG_MIPS_MT is present MIPS: Octeon: Remove special case for simulator command line. MIPS: tlbex: Properly fix HUGE TLB Refill exception handler MIPS: loongson2_cpufreq: Fix CPU clock rate setting mismerge pci: pci-lantiq: remove duplicate check on resource MIPS: Lasat: Add missing CONFIG_PROC_FS dependency to PICVUE_PROC MIPS: cp1emu: Fix ISA restrictions for cop1x_op instructions
This commit is contained in:
commit
2cc91884b6
@ -2066,6 +2066,7 @@ config MIPS_CPS
|
||||
support is unavailable.
|
||||
|
||||
config MIPS_CPS_PM
|
||||
depends on MIPS_CPS
|
||||
select MIPS_CPC
|
||||
bool
|
||||
|
||||
|
@ -113,7 +113,7 @@ static void __init db120_pci_init(u8 *eeprom)
|
||||
ath79_register_pci();
|
||||
}
|
||||
#else
|
||||
static inline void db120_pci_init(void) {}
|
||||
static inline void db120_pci_init(u8 *eeprom) {}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static void __init db120_setup(void)
|
||||
|
@ -806,15 +806,6 @@ void __init prom_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (octeon_is_simulation()) {
|
||||
/*
|
||||
* The simulator uses a mtdram device pre filled with
|
||||
* the filesystem. Also specify the calibration delay
|
||||
* to avoid calculating it every time.
|
||||
*/
|
||||
strcat(arcs_cmdline, " rw root=1f00 slram=root,0x40000000,+1073741824");
|
||||
}
|
||||
|
||||
mips_hpt_frequency = octeon_get_clock_rate();
|
||||
|
||||
octeon_init_cvmcount();
|
||||
|
@ -37,15 +37,15 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *);
|
||||
|
||||
#define cop2_present 1
|
||||
#define cop2_lazy_restore 1
|
||||
#define cop2_save(r) do { (r); } while (0)
|
||||
#define cop2_restore(r) do { (r); } while (0)
|
||||
#define cop2_save(r) do { (void)(r); } while (0)
|
||||
#define cop2_restore(r) do { (void)(r); } while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define cop2_present 0
|
||||
#define cop2_lazy_restore 0
|
||||
#define cop2_save(r) do { (r); } while (0)
|
||||
#define cop2_restore(r) do { (r); } while (0)
|
||||
#define cop2_save(r) do { (void)(r); } while (0)
|
||||
#define cop2_restore(r) do { (void)(r); } while (0)
|
||||
#endif
|
||||
|
||||
enum cu2_ops {
|
||||
|
@ -24,7 +24,7 @@ do { \
|
||||
asm volatile ( \
|
||||
"1: " load " %[tmp_dst], 0(%[tmp_src])\n" \
|
||||
" li %[tmp_err], 0\n" \
|
||||
"2:\n" \
|
||||
"2: .insn\n" \
|
||||
\
|
||||
".section .fixup, \"ax\"\n" \
|
||||
"3: li %[tmp_err], 1\n" \
|
||||
@ -46,7 +46,7 @@ do { \
|
||||
asm volatile ( \
|
||||
"1: " store " %[tmp_src], 0(%[tmp_dst])\n"\
|
||||
" li %[tmp_err], 0\n" \
|
||||
"2:\n" \
|
||||
"2: .insn\n" \
|
||||
\
|
||||
".section .fixup, \"ax\"\n" \
|
||||
"3: li %[tmp_err], 1\n" \
|
||||
|
@ -8,19 +8,12 @@ extern void (*cpu_wait)(void);
|
||||
extern void r4k_wait(void);
|
||||
extern asmlinkage void __r4k_wait(void);
|
||||
extern void r4k_wait_irqoff(void);
|
||||
extern void __pastwait(void);
|
||||
|
||||
static inline int using_rollback_handler(void)
|
||||
{
|
||||
return cpu_wait == r4k_wait;
|
||||
}
|
||||
|
||||
static inline int address_is_in_r4k_wait_irqoff(unsigned long addr)
|
||||
{
|
||||
return addr >= (unsigned long)r4k_wait_irqoff &&
|
||||
addr < (unsigned long)__pastwait;
|
||||
}
|
||||
|
||||
extern int mips_cpuidle_wait_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#ifndef _UAPI_ASM_PTRACE_H
|
||||
#define _UAPI_ASM_PTRACE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
|
||||
#define FPR_BASE 32
|
||||
#define PC 64
|
||||
|
@ -68,9 +68,6 @@ void r4k_wait_irqoff(void)
|
||||
" wait \n"
|
||||
" .set pop \n");
|
||||
local_irq_enable();
|
||||
__asm__(
|
||||
" .globl __pastwait \n"
|
||||
"__pastwait: \n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4,7 +4,7 @@ config PICVUE
|
||||
|
||||
config PICVUE_PROC
|
||||
tristate "PICVUE LCD display driver /proc interface"
|
||||
depends on PICVUE
|
||||
depends on PICVUE && PROC_FS
|
||||
|
||||
config DS1603
|
||||
bool "DS1603 RTC driver"
|
||||
|
@ -91,6 +91,7 @@ EXPORT_SYMBOL(clk_put);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned int rate_khz = rate / 1000;
|
||||
struct cpufreq_frequency_table *pos;
|
||||
int ret = 0;
|
||||
int regval;
|
||||
@ -107,9 +108,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
propagate_rate(clk);
|
||||
|
||||
cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table)
|
||||
if (rate == pos->frequency)
|
||||
if (rate_khz == pos->frequency)
|
||||
break;
|
||||
if (rate != pos->frequency)
|
||||
if (rate_khz != pos->frequency)
|
||||
return -ENOTSUPP;
|
||||
|
||||
clk->rate = rate;
|
||||
|
@ -1023,7 +1023,7 @@ emul:
|
||||
goto emul;
|
||||
|
||||
case cop1x_op:
|
||||
if (cpu_has_mips_4_5 || cpu_has_mips64)
|
||||
if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2)
|
||||
/* its one of ours */
|
||||
goto emul;
|
||||
|
||||
@ -1068,7 +1068,7 @@ emul:
|
||||
break;
|
||||
|
||||
case cop1x_op:
|
||||
if (!cpu_has_mips_4_5 && !cpu_has_mips64)
|
||||
if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2)
|
||||
return SIGILL;
|
||||
|
||||
sig = fpux_emu(xcp, ctx, ir, fault_addr);
|
||||
|
@ -1062,6 +1062,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
|
||||
struct mips_huge_tlb_info {
|
||||
int huge_pte;
|
||||
int restore_scratch;
|
||||
bool need_reload_pte;
|
||||
};
|
||||
|
||||
static struct mips_huge_tlb_info
|
||||
@ -1076,6 +1077,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
|
||||
|
||||
rv.huge_pte = scratch;
|
||||
rv.restore_scratch = 0;
|
||||
rv.need_reload_pte = false;
|
||||
|
||||
if (check_for_high_segbits) {
|
||||
UASM_i_MFC0(p, tmp, C0_BADVADDR);
|
||||
@ -1264,6 +1266,7 @@ static void build_r4000_tlb_refill_handler(void)
|
||||
} else {
|
||||
htlb_info.huge_pte = K0;
|
||||
htlb_info.restore_scratch = 0;
|
||||
htlb_info.need_reload_pte = true;
|
||||
vmalloc_mode = refill_noscratch;
|
||||
/*
|
||||
* create the plain linear handler
|
||||
@ -1300,7 +1303,8 @@ static void build_r4000_tlb_refill_handler(void)
|
||||
}
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
uasm_l_tlb_huge_update(&l, p);
|
||||
UASM_i_LW(&p, K0, 0, K1);
|
||||
if (htlb_info.need_reload_pte)
|
||||
UASM_i_LW(&p, htlb_info.huge_pte, 0, K1);
|
||||
build_huge_update_entries(&p, htlb_info.huge_pte, K1);
|
||||
build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
|
||||
htlb_info.restore_scratch);
|
||||
|
@ -5,8 +5,9 @@
|
||||
# Copyright (C) 2008 Wind River Systems, Inc.
|
||||
# written by Ralf Baechle <ralf@linux-mips.org>
|
||||
#
|
||||
obj-y := malta-amon.o malta-display.o malta-init.o \
|
||||
obj-y := malta-display.o malta-init.o \
|
||||
malta-int.o malta-memory.o malta-platform.o \
|
||||
malta-reset.o malta-setup.o malta-time.o
|
||||
|
||||
obj-$(CONFIG_MIPS_CMP) += malta-amon.o
|
||||
obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o
|
||||
|
@ -14,7 +14,6 @@ obj-y := sead3-lcd.o sead3-display.o sead3-init.o \
|
||||
sead3-setup.o sead3-time.o
|
||||
|
||||
obj-y += sead3-i2c-dev.o sead3-i2c.o \
|
||||
sead3-pic32-i2c-drv.o sead3-pic32-bus.o \
|
||||
leds-sead3.o sead3-leds.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o
|
||||
|
@ -5,10 +5,8 @@
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <irq.h>
|
||||
|
||||
struct resource sead3_i2c_resources[] = {
|
||||
{
|
||||
@ -30,8 +28,4 @@ static int __init sead3_i2c_init(void)
|
||||
return platform_device_register(&sead3_i2c_device);
|
||||
}
|
||||
|
||||
module_init(sead3_i2c_init);
|
||||
|
||||
MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("I2C probe driver for SEAD3");
|
||||
device_initcall(sead3_i2c_init);
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define PIC32_NULL 0x00
|
||||
#define PIC32_RD 0x01
|
||||
#define PIC32_SYSRD 0x02
|
||||
#define PIC32_WR 0x10
|
||||
#define PIC32_SYSWR 0x20
|
||||
#define PIC32_IRQ_CLR 0x40
|
||||
#define PIC32_STATUS 0x80
|
||||
|
||||
#define DELAY() udelay(100) /* FIXME: needed? */
|
||||
|
||||
/* spinlock to ensure atomic access to PIC32 */
|
||||
static DEFINE_SPINLOCK(pic32_bus_lock);
|
||||
|
||||
/* FIXME: io_remap these */
|
||||
static void __iomem *bus_xfer = (void __iomem *)0xbf000600;
|
||||
static void __iomem *bus_status = (void __iomem *)0xbf000060;
|
||||
|
||||
static inline unsigned int ioready(void)
|
||||
{
|
||||
return readl(bus_status) & 1;
|
||||
}
|
||||
|
||||
static inline void wait_ioready(void)
|
||||
{
|
||||
do { } while (!ioready());
|
||||
}
|
||||
|
||||
static inline void wait_ioclear(void)
|
||||
{
|
||||
do { } while (ioready());
|
||||
}
|
||||
|
||||
static inline void check_ioclear(void)
|
||||
{
|
||||
if (ioready()) {
|
||||
pr_debug("ioclear: initially busy\n");
|
||||
do {
|
||||
(void) readl(bus_xfer);
|
||||
DELAY();
|
||||
} while (ioready());
|
||||
pr_debug("ioclear: cleared busy\n");
|
||||
}
|
||||
}
|
||||
|
||||
u32 pic32_bus_readl(u32 reg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 status, val;
|
||||
|
||||
spin_lock_irqsave(&pic32_bus_lock, flags);
|
||||
|
||||
check_ioclear();
|
||||
|
||||
writel((PIC32_RD << 24) | (reg & 0x00ffffff), bus_xfer);
|
||||
DELAY();
|
||||
wait_ioready();
|
||||
status = readl(bus_xfer);
|
||||
DELAY();
|
||||
val = readl(bus_xfer);
|
||||
wait_ioclear();
|
||||
|
||||
pr_debug("pic32_bus_readl: *%x -> %x (status=%x)\n", reg, val, status);
|
||||
|
||||
spin_unlock_irqrestore(&pic32_bus_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void pic32_bus_writel(u32 val, u32 reg)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 status;
|
||||
|
||||
spin_lock_irqsave(&pic32_bus_lock, flags);
|
||||
|
||||
check_ioclear();
|
||||
|
||||
writel((PIC32_WR << 24) | (reg & 0x00ffffff), bus_xfer);
|
||||
DELAY();
|
||||
writel(val, bus_xfer);
|
||||
DELAY();
|
||||
wait_ioready();
|
||||
status = readl(bus_xfer);
|
||||
wait_ioclear();
|
||||
|
||||
pr_debug("pic32_bus_writel: *%x <- %x (status=%x)\n", reg, val, status);
|
||||
|
||||
spin_unlock_irqrestore(&pic32_bus_lock, flags);
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define PIC32_I2CxCON 0x0000
|
||||
#define PIC32_I2CxCONCLR 0x0004
|
||||
#define PIC32_I2CxCONSET 0x0008
|
||||
#define PIC32_I2CxCONINV 0x000C
|
||||
#define I2CCON_ON (1<<15)
|
||||
#define I2CCON_FRZ (1<<14)
|
||||
#define I2CCON_SIDL (1<<13)
|
||||
#define I2CCON_SCLREL (1<<12)
|
||||
#define I2CCON_STRICT (1<<11)
|
||||
#define I2CCON_A10M (1<<10)
|
||||
#define I2CCON_DISSLW (1<<9)
|
||||
#define I2CCON_SMEN (1<<8)
|
||||
#define I2CCON_GCEN (1<<7)
|
||||
#define I2CCON_STREN (1<<6)
|
||||
#define I2CCON_ACKDT (1<<5)
|
||||
#define I2CCON_ACKEN (1<<4)
|
||||
#define I2CCON_RCEN (1<<3)
|
||||
#define I2CCON_PEN (1<<2)
|
||||
#define I2CCON_RSEN (1<<1)
|
||||
#define I2CCON_SEN (1<<0)
|
||||
|
||||
#define PIC32_I2CxSTAT 0x0010
|
||||
#define PIC32_I2CxSTATCLR 0x0014
|
||||
#define PIC32_I2CxSTATSET 0x0018
|
||||
#define PIC32_I2CxSTATINV 0x001C
|
||||
#define I2CSTAT_ACKSTAT (1<<15)
|
||||
#define I2CSTAT_TRSTAT (1<<14)
|
||||
#define I2CSTAT_BCL (1<<10)
|
||||
#define I2CSTAT_GCSTAT (1<<9)
|
||||
#define I2CSTAT_ADD10 (1<<8)
|
||||
#define I2CSTAT_IWCOL (1<<7)
|
||||
#define I2CSTAT_I2COV (1<<6)
|
||||
#define I2CSTAT_DA (1<<5)
|
||||
#define I2CSTAT_P (1<<4)
|
||||
#define I2CSTAT_S (1<<3)
|
||||
#define I2CSTAT_RW (1<<2)
|
||||
#define I2CSTAT_RBF (1<<1)
|
||||
#define I2CSTAT_TBF (1<<0)
|
||||
|
||||
#define PIC32_I2CxADD 0x0020
|
||||
#define PIC32_I2CxADDCLR 0x0024
|
||||
#define PIC32_I2CxADDSET 0x0028
|
||||
#define PIC32_I2CxADDINV 0x002C
|
||||
#define PIC32_I2CxMSK 0x0030
|
||||
#define PIC32_I2CxMSKCLR 0x0034
|
||||
#define PIC32_I2CxMSKSET 0x0038
|
||||
#define PIC32_I2CxMSKINV 0x003C
|
||||
#define PIC32_I2CxBRG 0x0040
|
||||
#define PIC32_I2CxBRGCLR 0x0044
|
||||
#define PIC32_I2CxBRGSET 0x0048
|
||||
#define PIC32_I2CxBRGINV 0x004C
|
||||
#define PIC32_I2CxTRN 0x0050
|
||||
#define PIC32_I2CxTRNCLR 0x0054
|
||||
#define PIC32_I2CxTRNSET 0x0058
|
||||
#define PIC32_I2CxTRNINV 0x005C
|
||||
#define PIC32_I2CxRCV 0x0060
|
||||
|
||||
struct i2c_platform_data {
|
||||
u32 base;
|
||||
struct i2c_adapter adap;
|
||||
u32 xfer_timeout;
|
||||
u32 ack_timeout;
|
||||
u32 ctl_timeout;
|
||||
};
|
||||
|
||||
extern u32 pic32_bus_readl(u32 reg);
|
||||
extern void pic32_bus_writel(u32 val, u32 reg);
|
||||
|
||||
static inline void
|
||||
StartI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("StartI2C\n");
|
||||
pic32_bus_writel(I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
StopI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("StopI2C\n");
|
||||
pic32_bus_writel(I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
AckI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("AckI2C\n");
|
||||
pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
|
||||
pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
NotAckI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("NakI2C\n");
|
||||
pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
|
||||
pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
|
||||
}
|
||||
|
||||
static inline int
|
||||
IdleI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_debug("IdleI2C\n");
|
||||
for (i = 0; i < adap->ctl_timeout; i++) {
|
||||
if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
|
||||
(I2CCON_ACKEN | I2CCON_RCEN | I2CCON_PEN | I2CCON_RSEN |
|
||||
I2CCON_SEN)) == 0) &&
|
||||
((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
|
||||
(I2CSTAT_TRSTAT)) == 0))
|
||||
return 0;
|
||||
udelay(1);
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
MasterWriteI2C(struct i2c_platform_data *adap, u32 byte)
|
||||
{
|
||||
pr_debug("MasterWriteI2C\n");
|
||||
|
||||
pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
|
||||
|
||||
return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_IWCOL;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
MasterReadI2C(struct i2c_platform_data *adap)
|
||||
{
|
||||
pr_debug("MasterReadI2C\n");
|
||||
|
||||
pic32_bus_writel(I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
|
||||
|
||||
while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & I2CCON_RCEN)
|
||||
;
|
||||
|
||||
pic32_bus_writel(I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
|
||||
|
||||
return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
|
||||
}
|
||||
|
||||
static int
|
||||
do_address(struct i2c_platform_data *adap, unsigned int addr, int rd)
|
||||
{
|
||||
pr_debug("doaddress\n");
|
||||
|
||||
IdleI2C(adap);
|
||||
StartI2C(adap);
|
||||
IdleI2C(adap);
|
||||
|
||||
addr <<= 1;
|
||||
if (rd)
|
||||
addr |= 1;
|
||||
|
||||
if (MasterWriteI2C(adap, addr))
|
||||
return -EIO;
|
||||
IdleI2C(adap);
|
||||
if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_ACKSTAT)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_read(struct i2c_platform_data *adap, unsigned char *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int i;
|
||||
u32 data;
|
||||
|
||||
pr_debug("i2c_read\n");
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
data = MasterReadI2C(adap);
|
||||
buf[i++] = data;
|
||||
if (i < len)
|
||||
AckI2C(adap);
|
||||
else
|
||||
NotAckI2C(adap);
|
||||
}
|
||||
|
||||
StopI2C(adap);
|
||||
IdleI2C(adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_write(struct i2c_platform_data *adap, unsigned char *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int i;
|
||||
u32 data;
|
||||
|
||||
pr_debug("i2c_write\n");
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
data = buf[i];
|
||||
if (MasterWriteI2C(adap, data))
|
||||
return -EIO;
|
||||
IdleI2C(adap);
|
||||
if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
|
||||
I2CSTAT_ACKSTAT)
|
||||
return -EIO;
|
||||
i++;
|
||||
}
|
||||
|
||||
StopI2C(adap);
|
||||
IdleI2C(adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
platform_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
struct i2c_platform_data *adap = i2c_adap->algo_data;
|
||||
struct i2c_msg *p;
|
||||
int i, err = 0;
|
||||
|
||||
pr_debug("platform_xfer\n");
|
||||
for (i = 0; i < num; i++) {
|
||||
#define __BUFSIZE 80
|
||||
int ii;
|
||||
static char buf[__BUFSIZE];
|
||||
char *b = buf;
|
||||
|
||||
p = &msgs[i];
|
||||
b += sprintf(buf, " [%d bytes]", p->len);
|
||||
if ((p->flags & I2C_M_RD) == 0) {
|
||||
for (ii = 0; ii < p->len; ii++) {
|
||||
if (b < &buf[__BUFSIZE-4]) {
|
||||
b += sprintf(b, " %02x", p->buf[ii]);
|
||||
} else {
|
||||
strcat(b, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pr_debug("xfer%d: DevAddr: %04x Op:%s Data:%s\n", i, p->addr,
|
||||
(p->flags & I2C_M_RD) ? "Rd" : "Wr", buf);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; !err && i < num; i++) {
|
||||
p = &msgs[i];
|
||||
err = do_address(adap, p->addr, p->flags & I2C_M_RD);
|
||||
if (err || !p->len)
|
||||
continue;
|
||||
if (p->flags & I2C_M_RD)
|
||||
err = i2c_read(adap, p->buf, p->len);
|
||||
else
|
||||
err = i2c_write(adap, p->buf, p->len);
|
||||
}
|
||||
|
||||
/* Return the number of messages processed, or the error code. */
|
||||
if (err == 0)
|
||||
err = num;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32
|
||||
platform_func(struct i2c_adapter *adap)
|
||||
{
|
||||
pr_debug("platform_algo\n");
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm platform_algo = {
|
||||
.master_xfer = platform_xfer,
|
||||
.functionality = platform_func,
|
||||
};
|
||||
|
||||
static void i2c_platform_setup(struct i2c_platform_data *priv)
|
||||
{
|
||||
pr_debug("i2c_platform_setup\n");
|
||||
|
||||
pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
|
||||
pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
|
||||
pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONSET);
|
||||
pic32_bus_writel((I2CSTAT_BCL | I2CSTAT_IWCOL),
|
||||
(priv->base + PIC32_I2CxSTATCLR));
|
||||
}
|
||||
|
||||
static void i2c_platform_disable(struct i2c_platform_data *priv)
|
||||
{
|
||||
pr_debug("i2c_platform_disable\n");
|
||||
}
|
||||
|
||||
static int i2c_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv;
|
||||
struct resource *r;
|
||||
int ret;
|
||||
|
||||
pr_debug("i2c_platform_probe\n");
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r)
|
||||
return -ENODEV;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct i2c_platform_data),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* FIXME: need to allocate resource in PIC32 space */
|
||||
#if 0
|
||||
priv->base = bus_request_region(r->start, resource_size(r),
|
||||
pdev->name);
|
||||
#else
|
||||
priv->base = r->start;
|
||||
#endif
|
||||
if (!priv->base)
|
||||
return -EBUSY;
|
||||
|
||||
priv->xfer_timeout = 200;
|
||||
priv->ack_timeout = 200;
|
||||
priv->ctl_timeout = 200;
|
||||
|
||||
priv->adap.nr = pdev->id;
|
||||
priv->adap.algo = &platform_algo;
|
||||
priv->adap.algo_data = priv;
|
||||
priv->adap.dev.parent = &pdev->dev;
|
||||
strlcpy(priv->adap.name, "PIC32 I2C", sizeof(priv->adap.name));
|
||||
|
||||
i2c_platform_setup(priv);
|
||||
|
||||
ret = i2c_add_numbered_adapter(&priv->adap);
|
||||
if (ret) {
|
||||
i2c_platform_disable(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
pr_debug("i2c_platform_remove\n");
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
i2c_del_adapter(&priv->adap);
|
||||
i2c_platform_disable(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int
|
||||
i2c_platform_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
dev_dbg(&pdev->dev, "i2c_platform_disable\n");
|
||||
i2c_platform_disable(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i2c_platform_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_platform_data *priv = platform_get_drvdata(pdev);
|
||||
|
||||
dev_dbg(&pdev->dev, "i2c_platform_setup\n");
|
||||
i2c_platform_setup(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define i2c_platform_suspend NULL
|
||||
#define i2c_platform_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver i2c_platform_driver = {
|
||||
.driver = {
|
||||
.name = "i2c_pic32",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = i2c_platform_probe,
|
||||
.remove = i2c_platform_remove,
|
||||
.suspend = i2c_platform_suspend,
|
||||
.resume = i2c_platform_resume,
|
||||
};
|
||||
|
||||
static int __init
|
||||
i2c_platform_init(void)
|
||||
{
|
||||
pr_debug("i2c_platform_init\n");
|
||||
return platform_driver_register(&i2c_platform_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
i2c_platform_exit(void)
|
||||
{
|
||||
pr_debug("i2c_platform_exit\n");
|
||||
platform_driver_unregister(&i2c_platform_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
|
||||
MODULE_DESCRIPTION("PIC32 I2C driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(i2c_platform_init);
|
||||
module_exit(i2c_platform_exit);
|
@ -215,17 +215,12 @@ static int ltq_pci_probe(struct platform_device *pdev)
|
||||
|
||||
pci_clear_flags(PCI_PROBE_ONLY);
|
||||
|
||||
res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
res_bridge = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
if (!res_cfg || !res_bridge) {
|
||||
dev_err(&pdev->dev, "missing memory resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ltq_pci_membase = devm_ioremap_resource(&pdev->dev, res_bridge);
|
||||
if (IS_ERR(ltq_pci_membase))
|
||||
return PTR_ERR(ltq_pci_membase);
|
||||
|
||||
res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ltq_pci_mapped_cfg = devm_ioremap_resource(&pdev->dev, res_cfg);
|
||||
if (IS_ERR(ltq_pci_mapped_cfg))
|
||||
return PTR_ERR(ltq_pci_mapped_cfg);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <msp_int.h>
|
||||
|
||||
|
@ -131,11 +131,11 @@ static int msp_cic_irq_set_affinity(struct irq_data *d,
|
||||
int cpu;
|
||||
unsigned long flags;
|
||||
unsigned int mtflags;
|
||||
unsigned long imask = (1 << (irq - MSP_CIC_INTBASE));
|
||||
unsigned long imask = (1 << (d->irq - MSP_CIC_INTBASE));
|
||||
volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG;
|
||||
|
||||
/* timer balancing should be disabled in kernel code */
|
||||
BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER);
|
||||
BUG_ON(d->irq == MSP_INT_VPE0_TIMER || d->irq == MSP_INT_VPE1_TIMER);
|
||||
|
||||
LOCK_CORE(flags, mtflags);
|
||||
/* enable if any of each VPE's TCs require this IRQ */
|
||||
|
@ -25,3 +25,4 @@ obj-$(CONFIG_SIBYTE_RHONE) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_SENTOSA) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_SWARM) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_BIGSUR) += swarm/
|
||||
obj-$(CONFIG_SIBYTE_LITTLESUR) += swarm/
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
config MIPS_CPS_CPUIDLE
|
||||
bool "CPU Idle driver for MIPS CPS platforms"
|
||||
depends on CPU_IDLE
|
||||
depends on CPU_IDLE && MIPS_CPS
|
||||
depends on SYS_SUPPORTS_MIPS_CPS
|
||||
select ARCH_NEEDS_CPU_IDLE_COUPLED if MIPS_MT
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||
|
Loading…
Reference in New Issue
Block a user