mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 06:04:23 +08:00
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS fixes from Ralf Baechle: "Random fixes across the MIPS tree. The two hotspots are several bugs in the module loader and the ath79 SOC support; also noteworthy is the restructuring of the code to synchronize CPU timers across CPUs on startup; the old code recently ceased to work due to unrelated changes. All except one of these patches have sat for a significant time in linux-next for testing." * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: MIPS: pci-ar724x: avoid data bus error due to a missing PCIe module MIPS: Malta: Delete duplicate PCI fixup. MIPS: ath79: don't hardcode the unavailability of the DSP ASE MIPS: Synchronize MIPS count one CPU at a time MIPS: BCM63xx: Fix SPI message control register handling for BCM6338/6348. MIPS: Module: Deal with malformed HI16/LO16 relocation sequences. MIPS: Fix race condition in module relocation code. MIPS: Fix memory leak in error path of HI16/LO16 relocation handling. MIPS: MTX-1: Add udelay to mtx1_pci_idsel MIPS: ath79: select HAVE_CLK MIPS: ath79: Use correct IRQ number for the OHCI controller on AR7240 MIPS: ath79: Fix number of GPIO lines for AR724[12] MIPS: Octeon: Fix broken interrupt controller code.
This commit is contained in:
commit
2432cbe4f2
@ -89,6 +89,7 @@ config ATH79
|
||||
select CEVT_R4K
|
||||
select CSRC_R4K
|
||||
select DMA_NONCOHERENT
|
||||
select HAVE_CLK
|
||||
select IRQ_CPU
|
||||
select MIPS_MACHINE
|
||||
select SYS_HAS_CPU_MIPS32_R2
|
||||
|
@ -228,6 +228,8 @@ static int mtx1_pci_idsel(unsigned int devsel, int assert)
|
||||
* adapter on the mtx-1 "singleboard" variant. It triggers a custom
|
||||
* logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
|
||||
*/
|
||||
udelay(1);
|
||||
|
||||
if (assert && devsel != 0)
|
||||
/* Suppress signal to Cardbus */
|
||||
alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
|
||||
|
@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void)
|
||||
|
||||
ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
|
||||
ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
|
||||
ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB;
|
||||
ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;
|
||||
platform_device_register(&ath79_ohci_device);
|
||||
}
|
||||
|
||||
|
@ -188,8 +188,10 @@ void __init ath79_gpio_init(void)
|
||||
|
||||
if (soc_is_ar71xx())
|
||||
ath79_gpio_count = AR71XX_GPIO_COUNT;
|
||||
else if (soc_is_ar724x())
|
||||
ath79_gpio_count = AR724X_GPIO_COUNT;
|
||||
else if (soc_is_ar7240())
|
||||
ath79_gpio_count = AR7240_GPIO_COUNT;
|
||||
else if (soc_is_ar7241() || soc_is_ar7242())
|
||||
ath79_gpio_count = AR7241_GPIO_COUNT;
|
||||
else if (soc_is_ar913x())
|
||||
ath79_gpio_count = AR913X_GPIO_COUNT;
|
||||
else if (soc_is_ar933x())
|
||||
|
@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void)
|
||||
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
|
||||
spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
|
||||
spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
|
||||
spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT;
|
||||
spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
|
||||
}
|
||||
|
||||
if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
|
||||
spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
|
||||
spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
|
||||
spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
|
||||
spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
|
||||
}
|
||||
|
||||
bcm63xx_spi_regs_init();
|
||||
|
@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
|
||||
octeon_irq_ciu_to_irq[line][bit] = irq;
|
||||
}
|
||||
|
||||
static void octeon_irq_force_ciu_mapping(struct irq_domain *domain,
|
||||
int irq, int line, int bit)
|
||||
{
|
||||
irq_domain_associate(domain, irq, line << 6 | bit);
|
||||
}
|
||||
|
||||
static int octeon_coreid_for_cpu(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void)
|
||||
mutex_init(&cd->core_irq_mutex);
|
||||
|
||||
irq = OCTEON_IRQ_SW0 + i;
|
||||
switch (irq) {
|
||||
case OCTEON_IRQ_TIMER:
|
||||
case OCTEON_IRQ_SW0:
|
||||
case OCTEON_IRQ_SW1:
|
||||
case OCTEON_IRQ_5:
|
||||
case OCTEON_IRQ_PERF:
|
||||
irq_set_chip_data(irq, cd);
|
||||
irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
|
||||
handle_percpu_irq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
irq_set_chip_data(irq, cd);
|
||||
irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
|
||||
handle_percpu_irq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
|
||||
unsigned int type;
|
||||
unsigned int pin;
|
||||
unsigned int trigger;
|
||||
struct octeon_irq_gpio_domain_data *gpiod;
|
||||
|
||||
if (d->of_node != node)
|
||||
return -EINVAL;
|
||||
@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,
|
||||
break;
|
||||
}
|
||||
*out_type = type;
|
||||
gpiod = d->host_data;
|
||||
*out_hwirq = gpiod->base_hwirq + pin;
|
||||
*out_hwirq = pin;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
|
||||
static int octeon_irq_gpio_map(struct irq_domain *d,
|
||||
unsigned int virq, irq_hw_number_t hw)
|
||||
{
|
||||
unsigned int line = hw >> 6;
|
||||
unsigned int bit = hw & 63;
|
||||
struct octeon_irq_gpio_domain_data *gpiod = d->host_data;
|
||||
unsigned int line, bit;
|
||||
|
||||
if (!octeon_irq_virq_in_range(virq))
|
||||
return -EINVAL;
|
||||
|
||||
hw += gpiod->base_hwirq;
|
||||
line = hw >> 6;
|
||||
bit = hw & 63;
|
||||
if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
|
||||
return -EINVAL;
|
||||
|
||||
octeon_irq_set_ciu_mapping(virq, line, bit,
|
||||
octeon_irq_gpio_chip,
|
||||
octeon_irq_handle_gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void)
|
||||
struct irq_chip *chip_wd;
|
||||
struct device_node *gpio_node;
|
||||
struct device_node *ciu_node;
|
||||
struct irq_domain *ciu_domain = NULL;
|
||||
|
||||
octeon_irq_init_ciu_percpu();
|
||||
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
|
||||
@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void)
|
||||
/* Mips internal */
|
||||
octeon_irq_init_core();
|
||||
|
||||
/* CIU_0 */
|
||||
for (i = 0; i < 16; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
|
||||
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
|
||||
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq);
|
||||
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
|
||||
|
||||
/* CIU_1 */
|
||||
for (i = 0; i < 16; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
|
||||
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
|
||||
|
||||
gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
|
||||
if (gpio_node) {
|
||||
struct octeon_irq_gpio_domain_data *gpiod;
|
||||
@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void)
|
||||
|
||||
ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
|
||||
if (ciu_node) {
|
||||
irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
|
||||
ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
|
||||
of_node_put(ciu_node);
|
||||
} else
|
||||
pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n");
|
||||
panic("Cannot find device node for cavium,octeon-3860-ciu.");
|
||||
|
||||
/* CIU_0 */
|
||||
for (i = 0; i < 16; i++)
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0);
|
||||
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
|
||||
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36);
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40);
|
||||
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46);
|
||||
for (i = 0; i < 4; i++)
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52);
|
||||
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56);
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63);
|
||||
|
||||
/* CIU_1 */
|
||||
for (i = 0; i < 16; i++)
|
||||
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
|
||||
|
||||
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);
|
||||
|
||||
/* Enable the CIU lines */
|
||||
set_c0_status(STATUSF_IP3 | STATUSF_IP2);
|
||||
|
@ -393,7 +393,8 @@
|
||||
#define AR71XX_GPIO_REG_FUNC 0x28
|
||||
|
||||
#define AR71XX_GPIO_COUNT 16
|
||||
#define AR724X_GPIO_COUNT 18
|
||||
#define AR7240_GPIO_COUNT 18
|
||||
#define AR7241_GPIO_COUNT 20
|
||||
#define AR913X_GPIO_COUNT 22
|
||||
#define AR933X_GPIO_COUNT 30
|
||||
#define AR934X_GPIO_COUNT 23
|
||||
|
@ -42,7 +42,6 @@
|
||||
#define cpu_has_mips64r1 0
|
||||
#define cpu_has_mips64r2 0
|
||||
|
||||
#define cpu_has_dsp 0
|
||||
#define cpu_has_mipsmt 0
|
||||
|
||||
#define cpu_has_64bits 0
|
||||
|
@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void);
|
||||
|
||||
struct bcm63xx_spi_pdata {
|
||||
unsigned int fifo_size;
|
||||
unsigned int msg_type_shift;
|
||||
unsigned int msg_ctl_width;
|
||||
int bus_num;
|
||||
int num_chipselect;
|
||||
u32 speed_hz;
|
||||
|
@ -1054,7 +1054,8 @@
|
||||
#define SPI_6338_FILL_BYTE 0x07
|
||||
#define SPI_6338_MSG_TAIL 0x09
|
||||
#define SPI_6338_RX_TAIL 0x0b
|
||||
#define SPI_6338_MSG_CTL 0x40
|
||||
#define SPI_6338_MSG_CTL 0x40 /* 8-bits register */
|
||||
#define SPI_6338_MSG_CTL_WIDTH 8
|
||||
#define SPI_6338_MSG_DATA 0x41
|
||||
#define SPI_6338_MSG_DATA_SIZE 0x3f
|
||||
#define SPI_6338_RX_DATA 0x80
|
||||
@ -1070,7 +1071,8 @@
|
||||
#define SPI_6348_FILL_BYTE 0x07
|
||||
#define SPI_6348_MSG_TAIL 0x09
|
||||
#define SPI_6348_RX_TAIL 0x0b
|
||||
#define SPI_6348_MSG_CTL 0x40
|
||||
#define SPI_6348_MSG_CTL 0x40 /* 8-bits register */
|
||||
#define SPI_6348_MSG_CTL_WIDTH 8
|
||||
#define SPI_6348_MSG_DATA 0x41
|
||||
#define SPI_6348_MSG_DATA_SIZE 0x3f
|
||||
#define SPI_6348_RX_DATA 0x80
|
||||
@ -1078,6 +1080,7 @@
|
||||
|
||||
/* BCM 6358 SPI core */
|
||||
#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */
|
||||
#define SPI_6358_MSG_CTL_WIDTH 16
|
||||
#define SPI_6358_MSG_DATA 0x02
|
||||
#define SPI_6358_MSG_DATA_SIZE 0x21e
|
||||
#define SPI_6358_RX_DATA 0x400
|
||||
@ -1094,6 +1097,7 @@
|
||||
|
||||
/* BCM 6358 SPI core */
|
||||
#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */
|
||||
#define SPI_6368_MSG_CTL_WIDTH 16
|
||||
#define SPI_6368_MSG_DATA 0x02
|
||||
#define SPI_6368_MSG_DATA_SIZE 0x21e
|
||||
#define SPI_6368_RX_DATA 0x400
|
||||
@ -1115,7 +1119,10 @@
|
||||
#define SPI_HD_W 0x01
|
||||
#define SPI_HD_R 0x02
|
||||
#define SPI_BYTE_CNT_SHIFT 0
|
||||
#define SPI_MSG_TYPE_SHIFT 14
|
||||
#define SPI_6338_MSG_TYPE_SHIFT 6
|
||||
#define SPI_6348_MSG_TYPE_SHIFT 6
|
||||
#define SPI_6358_MSG_TYPE_SHIFT 14
|
||||
#define SPI_6368_MSG_TYPE_SHIFT 14
|
||||
|
||||
/* Command */
|
||||
#define SPI_CMD_NOOP 0x00
|
||||
|
@ -21,14 +21,10 @@ enum octeon_irq {
|
||||
OCTEON_IRQ_TIMER,
|
||||
/* sources in CIU_INTX_EN0 */
|
||||
OCTEON_IRQ_WORKQ0,
|
||||
OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
|
||||
OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
|
||||
OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16,
|
||||
OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
|
||||
OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
|
||||
OCTEON_IRQ_MBOX1,
|
||||
OCTEON_IRQ_UART0,
|
||||
OCTEON_IRQ_UART1,
|
||||
OCTEON_IRQ_UART2,
|
||||
OCTEON_IRQ_PCI_INT0,
|
||||
OCTEON_IRQ_PCI_INT1,
|
||||
OCTEON_IRQ_PCI_INT2,
|
||||
@ -38,8 +34,6 @@ enum octeon_irq {
|
||||
OCTEON_IRQ_PCI_MSI2,
|
||||
OCTEON_IRQ_PCI_MSI3,
|
||||
|
||||
OCTEON_IRQ_TWSI,
|
||||
OCTEON_IRQ_TWSI2,
|
||||
OCTEON_IRQ_RML,
|
||||
OCTEON_IRQ_TIMER0,
|
||||
OCTEON_IRQ_TIMER1,
|
||||
@ -47,8 +41,6 @@ enum octeon_irq {
|
||||
OCTEON_IRQ_TIMER3,
|
||||
OCTEON_IRQ_USB0,
|
||||
OCTEON_IRQ_USB1,
|
||||
OCTEON_IRQ_MII0,
|
||||
OCTEON_IRQ_MII1,
|
||||
OCTEON_IRQ_BOOTDMA,
|
||||
#ifndef CONFIG_PCI_MSI
|
||||
OCTEON_IRQ_LAST = 127
|
||||
|
@ -10,6 +10,7 @@ struct mod_arch_specific {
|
||||
struct list_head dbe_list;
|
||||
const struct exception_table_entry *dbe_start;
|
||||
const struct exception_table_entry *dbe_end;
|
||||
struct mips_hi16 *r_mips_hi16_list;
|
||||
};
|
||||
|
||||
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
|
||||
|
@ -12,16 +12,16 @@
|
||||
|
||||
#ifdef CONFIG_SYNC_R4K
|
||||
|
||||
extern void synchronise_count_master(void);
|
||||
extern void synchronise_count_slave(void);
|
||||
extern void synchronise_count_master(int cpu);
|
||||
extern void synchronise_count_slave(int cpu);
|
||||
|
||||
#else
|
||||
|
||||
static inline void synchronise_count_master(void)
|
||||
static inline void synchronise_count_master(int cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void synchronise_count_slave(void)
|
||||
static inline void synchronise_count_slave(int cpu)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,6 @@ struct mips_hi16 {
|
||||
Elf_Addr value;
|
||||
};
|
||||
|
||||
static struct mips_hi16 *mips_hi16_list;
|
||||
|
||||
static LIST_HEAD(dbe_list);
|
||||
static DEFINE_SPINLOCK(dbe_lock);
|
||||
|
||||
@ -128,8 +126,8 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
|
||||
n->addr = (Elf_Addr *)location;
|
||||
n->value = v;
|
||||
n->next = mips_hi16_list;
|
||||
mips_hi16_list = n;
|
||||
n->next = me->arch.r_mips_hi16_list;
|
||||
me->arch.r_mips_hi16_list = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -142,18 +140,28 @@ static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_relocation_chain(struct mips_hi16 *l)
|
||||
{
|
||||
struct mips_hi16 *next;
|
||||
|
||||
while (l) {
|
||||
next = l->next;
|
||||
kfree(l);
|
||||
l = next;
|
||||
}
|
||||
}
|
||||
|
||||
static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
{
|
||||
unsigned long insnlo = *location;
|
||||
struct mips_hi16 *l;
|
||||
Elf_Addr val, vallo;
|
||||
|
||||
/* Sign extend the addend we extract from the lo insn. */
|
||||
vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
|
||||
|
||||
if (mips_hi16_list != NULL) {
|
||||
struct mips_hi16 *l;
|
||||
|
||||
l = mips_hi16_list;
|
||||
if (me->arch.r_mips_hi16_list != NULL) {
|
||||
l = me->arch.r_mips_hi16_list;
|
||||
while (l != NULL) {
|
||||
struct mips_hi16 *next;
|
||||
unsigned long insn;
|
||||
@ -188,7 +196,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
l = next;
|
||||
}
|
||||
|
||||
mips_hi16_list = NULL;
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -201,6 +209,9 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
return 0;
|
||||
|
||||
out_danger:
|
||||
free_relocation_chain(l);
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
|
||||
pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name);
|
||||
|
||||
return -ENOEXEC;
|
||||
@ -273,6 +284,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
||||
pr_debug("Applying relocate section %u to %u\n", relsec,
|
||||
sechdrs[relsec].sh_info);
|
||||
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
|
||||
/* This is where to make the change */
|
||||
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
|
||||
@ -296,6 +308,19 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normally the hi16 list should be deallocated at this point. A
|
||||
* malformed binary however could contain a series of R_MIPS_HI16
|
||||
* relocations not followed by a R_MIPS_LO16 relocation. In that
|
||||
* case, free up the list and return an error.
|
||||
*/
|
||||
if (me->arch.r_mips_hi16_list) {
|
||||
free_relocation_chain(me->arch.r_mips_hi16_list);
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ asmlinkage __cpuinit void start_secondary(void)
|
||||
|
||||
cpu_set(cpu, cpu_callin_map);
|
||||
|
||||
synchronise_count_slave();
|
||||
synchronise_count_slave(cpu);
|
||||
|
||||
/*
|
||||
* irq will be enabled in ->smp_finish(), enabling it too early
|
||||
@ -173,7 +173,6 @@ void smp_send_stop(void)
|
||||
void __init smp_cpus_done(unsigned int max_cpus)
|
||||
{
|
||||
mp_ops->cpus_done();
|
||||
synchronise_count_master();
|
||||
}
|
||||
|
||||
/* called from main before smp_init() */
|
||||
@ -206,6 +205,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||
while (!cpu_isset(cpu, cpu_callin_map))
|
||||
udelay(100);
|
||||
|
||||
synchronise_count_master(cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -28,12 +28,11 @@ static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);
|
||||
#define COUNTON 100
|
||||
#define NR_LOOPS 5
|
||||
|
||||
void __cpuinit synchronise_count_master(void)
|
||||
void __cpuinit synchronise_count_master(int cpu)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
unsigned int initcount;
|
||||
int nslaves;
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
@ -43,8 +42,7 @@ void __cpuinit synchronise_count_master(void)
|
||||
return;
|
||||
#endif
|
||||
|
||||
printk(KERN_INFO "Synchronize counters across %u CPUs: ",
|
||||
num_online_cpus());
|
||||
printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
@ -52,7 +50,7 @@ void __cpuinit synchronise_count_master(void)
|
||||
* Notify the slaves that it's time to start
|
||||
*/
|
||||
atomic_set(&count_reference, read_c0_count());
|
||||
atomic_set(&count_start_flag, 1);
|
||||
atomic_set(&count_start_flag, cpu);
|
||||
smp_wmb();
|
||||
|
||||
/* Count will be initialised to current timer for all CPU's */
|
||||
@ -69,10 +67,9 @@ void __cpuinit synchronise_count_master(void)
|
||||
* two CPUs.
|
||||
*/
|
||||
|
||||
nslaves = num_online_cpus()-1;
|
||||
for (i = 0; i < NR_LOOPS; i++) {
|
||||
/* slaves loop on '!= ncpus' */
|
||||
while (atomic_read(&count_count_start) != nslaves)
|
||||
/* slaves loop on '!= 2' */
|
||||
while (atomic_read(&count_count_start) != 1)
|
||||
mb();
|
||||
atomic_set(&count_count_stop, 0);
|
||||
smp_wmb();
|
||||
@ -89,7 +86,7 @@ void __cpuinit synchronise_count_master(void)
|
||||
/*
|
||||
* Wait for all slaves to leave the synchronization point:
|
||||
*/
|
||||
while (atomic_read(&count_count_stop) != nslaves)
|
||||
while (atomic_read(&count_count_stop) != 1)
|
||||
mb();
|
||||
atomic_set(&count_count_start, 0);
|
||||
smp_wmb();
|
||||
@ -97,6 +94,7 @@ void __cpuinit synchronise_count_master(void)
|
||||
}
|
||||
/* Arrange for an interrupt in a short while */
|
||||
write_c0_compare(read_c0_count() + COUNTON);
|
||||
atomic_set(&count_start_flag, 0);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
@ -108,11 +106,10 @@ void __cpuinit synchronise_count_master(void)
|
||||
printk("done.\n");
|
||||
}
|
||||
|
||||
void __cpuinit synchronise_count_slave(void)
|
||||
void __cpuinit synchronise_count_slave(int cpu)
|
||||
{
|
||||
int i;
|
||||
unsigned int initcount;
|
||||
int ncpus;
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
@ -127,16 +124,15 @@ void __cpuinit synchronise_count_slave(void)
|
||||
* so we first wait for the master to say everyone is ready
|
||||
*/
|
||||
|
||||
while (!atomic_read(&count_start_flag))
|
||||
while (atomic_read(&count_start_flag) != cpu)
|
||||
mb();
|
||||
|
||||
/* Count will be initialised to next expire for all CPU's */
|
||||
initcount = atomic_read(&count_reference);
|
||||
|
||||
ncpus = num_online_cpus();
|
||||
for (i = 0; i < NR_LOOPS; i++) {
|
||||
atomic_inc(&count_count_start);
|
||||
while (atomic_read(&count_count_start) != ncpus)
|
||||
while (atomic_read(&count_count_start) != 2)
|
||||
mb();
|
||||
|
||||
/*
|
||||
@ -146,7 +142,7 @@ void __cpuinit synchronise_count_slave(void)
|
||||
write_c0_count(initcount);
|
||||
|
||||
atomic_inc(&count_count_stop);
|
||||
while (atomic_read(&count_count_stop) != ncpus)
|
||||
while (atomic_read(&count_count_stop) != 2)
|
||||
mb();
|
||||
}
|
||||
/* Arrange for an interrupt in a short while */
|
||||
|
@ -252,16 +252,3 @@ void __init mips_pcibios_init(void)
|
||||
|
||||
register_pci_controller(controller);
|
||||
}
|
||||
|
||||
/* Enable PCI 2.1 compatibility in PIIX4 */
|
||||
static void __devinit quirk_dlcsetup(struct pci_dev *dev)
|
||||
{
|
||||
u8 odlc, ndlc;
|
||||
(void) pci_read_config_byte(dev, 0x82, &odlc);
|
||||
/* Enable passive releases and delayed transaction */
|
||||
ndlc = odlc | 7;
|
||||
(void) pci_write_config_byte(dev, 0x82, ndlc);
|
||||
}
|
||||
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
|
||||
quirk_dlcsetup);
|
||||
|
@ -23,9 +23,12 @@
|
||||
#define AR724X_PCI_MEM_BASE 0x10000000
|
||||
#define AR724X_PCI_MEM_SIZE 0x08000000
|
||||
|
||||
#define AR724X_PCI_REG_RESET 0x18
|
||||
#define AR724X_PCI_REG_INT_STATUS 0x4c
|
||||
#define AR724X_PCI_REG_INT_MASK 0x50
|
||||
|
||||
#define AR724X_PCI_RESET_LINK_UP BIT(0)
|
||||
|
||||
#define AR724X_PCI_INT_DEV0 BIT(14)
|
||||
|
||||
#define AR724X_PCI_IRQ_COUNT 1
|
||||
@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_base;
|
||||
|
||||
static u32 ar724x_pci_bar0_value;
|
||||
static bool ar724x_pci_bar0_is_cached;
|
||||
static bool ar724x_pci_link_up;
|
||||
|
||||
static inline bool ar724x_pci_check_link(void)
|
||||
{
|
||||
u32 reset;
|
||||
|
||||
reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
|
||||
return reset & AR724X_PCI_RESET_LINK_UP;
|
||||
}
|
||||
|
||||
static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
int size, uint32_t *value)
|
||||
@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
void __iomem *base;
|
||||
u32 data;
|
||||
|
||||
if (!ar724x_pci_link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (devfn)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
u32 data;
|
||||
int s;
|
||||
|
||||
if (!ar724x_pci_link_up)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
if (devfn)
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq)
|
||||
if (ar724x_pci_ctrl_base == NULL)
|
||||
goto err_unmap_devcfg;
|
||||
|
||||
ar724x_pci_link_up = ar724x_pci_check_link();
|
||||
if (!ar724x_pci_link_up)
|
||||
pr_warn("ar724x: PCIe link is down\n");
|
||||
|
||||
ar724x_pci_irq_init(irq);
|
||||
register_pci_controller(&ar724x_pci_controller);
|
||||
|
||||
|
@ -47,6 +47,8 @@ struct bcm63xx_spi {
|
||||
/* Platform data */
|
||||
u32 speed_hz;
|
||||
unsigned fifo_size;
|
||||
unsigned int msg_type_shift;
|
||||
unsigned int msg_ctl_width;
|
||||
|
||||
/* Data buffers */
|
||||
const unsigned char *tx_ptr;
|
||||
@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
|
||||
msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
|
||||
|
||||
if (t->rx_buf && t->tx_buf)
|
||||
msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT);
|
||||
msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
|
||||
else if (t->rx_buf)
|
||||
msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT);
|
||||
msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
|
||||
else if (t->tx_buf)
|
||||
msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT);
|
||||
msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
|
||||
|
||||
bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
|
||||
switch (bs->msg_ctl_width) {
|
||||
case 8:
|
||||
bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
|
||||
break;
|
||||
case 16:
|
||||
bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Issue the transfer */
|
||||
cmd = SPI_CMD_START_IMMEDIATE;
|
||||
@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
|
||||
master->transfer_one_message = bcm63xx_spi_transfer_one;
|
||||
master->mode_bits = MODEBITS;
|
||||
bs->speed_hz = pdata->speed_hz;
|
||||
bs->msg_type_shift = pdata->msg_type_shift;
|
||||
bs->msg_ctl_width = pdata->msg_ctl_width;
|
||||
bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
|
||||
bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));
|
||||
|
||||
switch (bs->msg_ctl_width) {
|
||||
case 8:
|
||||
case 16:
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "unsupported MSG_CTL width: %d\n",
|
||||
bs->msg_ctl_width);
|
||||
goto out_clk_disable;
|
||||
}
|
||||
|
||||
/* Initialize hardware */
|
||||
clk_enable(bs->clk);
|
||||
bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
|
||||
|
Loading…
Reference in New Issue
Block a user