Skip to content

Commit

Permalink
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-…
Browse files Browse the repository at this point in the history
…linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
  [MIPS] Fix EV64120 and Ocelot builds by providing a plat_timer_setup().
  [MIPS] EV64120: Fix PCI interrupt allocation.
  [MIPS] Make irq number allocator generally available for fixing EV64120.
  [MIPS] EV64120: Fix timer initialization for HZ != 100.
  [MIPS] Ocelot 3: Fix MAC address detection after platform_device conversion.
  [MIPS] Ocelot C: Fix MAC address detection after platform_device conversion.
  [MIPS] SB1: On bootup only flush cache on local CPU.
  [MIPS] Ocelot 3: Fix large number of warnings.
  [MIPS] Ocelot C: Fix mapping of ioport address range.
  [MIPS] Ocelot C: Fix warning about missmatching format string.
  [MIPS] Ocelot C: fix eth registration after conversion to platform_device
  [MIPS] Ocelot C: Fix large number of warnings.
  • Loading branch information
Linus Torvalds committed Nov 7, 2006
2 parents 846cf85 + 73f4388 commit c836b77
Show file tree
Hide file tree
Showing 21 changed files with 528 additions and 206 deletions.
4 changes: 2 additions & 2 deletions arch/mips/gt64120/common/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ static irqreturn_t gt64120_irq(int irq, void *dev_id)
* as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt
* handling.
*/
void gt64120_time_init(void)
void __init plat_timer_setup(struct irqaction *irq)
{
static struct irqaction timer;

/* Disable timer first */
GT_WRITE(GT_TC_CONTROL_OFS, 0);
/* Load timer value for 100 Hz */
GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
GT_WRITE(GT_TC3_OFS, Sys_clock / HZ);

/*
* Create the IRQ structure entry for the timer. Since we're too early
Expand Down
2 changes: 0 additions & 2 deletions arch/mips/gt64120/ev64120/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,13 @@ unsigned long __init prom_free_prom_memory(void)
* Initializes basic routines and structures pointers, memory size (as
* given by the bios and saves the command line.
*/
extern void gt64120_time_init(void);

void __init plat_mem_setup(void)
{
_machine_restart = galileo_machine_restart;
_machine_halt = galileo_machine_halt;
pm_power_off = galileo_machine_power_off;

board_time_init = gt64120_time_init;
set_io_port_base(KSEG1);
}

Expand Down
3 changes: 0 additions & 3 deletions arch/mips/gt64120/momenco_ocelot/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ extern void momenco_ocelot_restart(char *command);
extern void momenco_ocelot_halt(void);
extern void momenco_ocelot_power_off(void);

extern void gt64120_time_init(void);
extern void momenco_ocelot_irq_setup(void);

static char reset_reason;
Expand Down Expand Up @@ -156,8 +155,6 @@ void __init plat_mem_setup(void)
void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
unsigned int tmpword;

board_time_init = gt64120_time_init;

_machine_restart = momenco_ocelot_restart;
_machine_halt = momenco_ocelot_halt;
pm_power_off = momenco_ocelot_power_off;
Expand Down
42 changes: 42 additions & 0 deletions arch/mips/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,48 @@
#include <asm/system.h>
#include <asm/uaccess.h>

static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];

int __devinit allocate_irqno(void)
{
int irq;

again:
irq = find_first_zero_bit(irq_map, NR_IRQS);

if (irq >= NR_IRQS)
return -ENOSPC;

if (test_and_set_bit(irq, irq_map))
goto again;

return irq;
}

EXPORT_SYMBOL_GPL(allocate_irqno);

/*
* Allocate the 16 legacy interrupts for i8259 devices. This happens early
* in the kernel initialization so treating allocation failure as BUG() is
* ok.
*/
void __init alloc_legacy_irqno(void)
{
int i;

for (i = 0; i <= 16; i++)
BUG_ON(test_and_set_bit(i, irq_map));
}

void __devinit free_irqno(unsigned int irq)
{
smp_mb__before_clear_bit();
clear_bit(irq, irq_map);
smp_mb__after_clear_bit();
}

EXPORT_SYMBOL_GPL(free_irqno);

/*
* 'what should we do if we get a hw irq event on an illegal vector'.
* each architecture has to answer this themselves.
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/mm/c-sb1.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,5 +505,5 @@ void sb1_cache_init(void)
:
: "memory");

flush_cache_all();
local_sb1___flush_cache_all();
}
2 changes: 1 addition & 1 deletion arch/mips/momentum/ocelot_3/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
obj-y += irq.o prom.o reset.o setup.o
obj-y += irq.o platform.o prom.o reset.o setup.o
6 changes: 4 additions & 2 deletions arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@

extern unsigned long ocelot_fpga_base;

#define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y)
#define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x)
#define __FPGA_REG_TO_ADDR(reg) \
((void *) ocelot_fpga_base + OCELOT_3_REG_##reg)
#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))

#endif
235 changes: 235 additions & 0 deletions arch/mips/momentum/ocelot_3/platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#include <linux/delay.h>
#include <linux/if_ether.h>
#include <linux/ioport.h>
#include <linux/mv643xx.h>
#include <linux/platform_device.h>

#include "ocelot_3_fpga.h"

#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)

static struct resource mv643xx_eth_shared_resources[] = {
[0] = {
.name = "ethernet shared base",
.start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
.end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
MV643XX_ETH_SHARED_REGS_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};

static struct platform_device mv643xx_eth_shared_device = {
.name = MV643XX_ETH_SHARED_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
.resource = mv643xx_eth_shared_resources,
};

#define MV_SRAM_BASE 0xfe000000UL
#define MV_SRAM_SIZE (256 * 1024)

#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)

#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))

#define MV64x60_IRQ_ETH_0 48
#define MV64x60_IRQ_ETH_1 49
#define MV64x60_IRQ_ETH_2 50

#ifdef CONFIG_MV643XX_ETH_0

static struct resource mv64x60_eth0_resources[] = {
[0] = {
.name = "eth0 irq",
.start = MV64x60_IRQ_ETH_0,
.end = MV64x60_IRQ_ETH_0,
.flags = IORESOURCE_IRQ,
},
};

static char eth0_mac_addr[ETH_ALEN];

static struct mv643xx_eth_platform_data eth0_pd = {
.mac_addr = eth0_mac_addr,

.tx_sram_addr = MV_SRAM_BASE_ETH0,
.tx_sram_size = MV_SRAM_TXRING_SIZE,
.tx_queue_size = MV_SRAM_TXRING_SIZE / 16,

.rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
.rx_sram_size = MV_SRAM_RXRING_SIZE,
.rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
};

static struct platform_device eth0_device = {
.name = MV643XX_ETH_NAME,
.id = 0,
.num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
.resource = mv64x60_eth0_resources,
.dev = {
.platform_data = &eth0_pd,
},
};
#endif /* CONFIG_MV643XX_ETH_0 */

#ifdef CONFIG_MV643XX_ETH_1

static struct resource mv64x60_eth1_resources[] = {
[0] = {
.name = "eth1 irq",
.start = MV64x60_IRQ_ETH_1,
.end = MV64x60_IRQ_ETH_1,
.flags = IORESOURCE_IRQ,
},
};

static char eth1_mac_addr[ETH_ALEN];

static struct mv643xx_eth_platform_data eth1_pd = {
.mac_addr = eth1_mac_addr,

.tx_sram_addr = MV_SRAM_BASE_ETH1,
.tx_sram_size = MV_SRAM_TXRING_SIZE,
.tx_queue_size = MV_SRAM_TXRING_SIZE / 16,

.rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
.rx_sram_size = MV_SRAM_RXRING_SIZE,
.rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
};

static struct platform_device eth1_device = {
.name = MV643XX_ETH_NAME,
.id = 1,
.num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
.resource = mv64x60_eth1_resources,
.dev = {
.platform_data = &eth1_pd,
},
};
#endif /* CONFIG_MV643XX_ETH_1 */

#ifdef CONFIG_MV643XX_ETH_2

static struct resource mv64x60_eth2_resources[] = {
[0] = {
.name = "eth2 irq",
.start = MV64x60_IRQ_ETH_2,
.end = MV64x60_IRQ_ETH_2,
.flags = IORESOURCE_IRQ,
},
};

static char eth2_mac_addr[ETH_ALEN];

static struct mv643xx_eth_platform_data eth2_pd = {
.mac_addr = eth2_mac_addr,
};

static struct platform_device eth2_device = {
.name = MV643XX_ETH_NAME,
.id = 1,
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
.resource = mv64x60_eth2_resources,
.dev = {
.platform_data = &eth2_pd,
},
};
#endif /* CONFIG_MV643XX_ETH_2 */

static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&mv643xx_eth_shared_device,
#ifdef CONFIG_MV643XX_ETH_0
&eth0_device,
#endif
#ifdef CONFIG_MV643XX_ETH_1
&eth1_device,
#endif
#ifdef CONFIG_MV643XX_ETH_2
&eth2_device,
#endif
};

static u8 __init exchange_bit(u8 val, u8 cs)
{
/* place the data */
OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
udelay(1);

/* turn the clock on */
OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
udelay(1);

/* turn the clock off and read-strobe */
OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);

/* return the data */
return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
}

static void __init get_mac(char dest[6])
{
u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int i,j;

for (i = 0; i < 12; i++)
exchange_bit(read_opcode[i], 1);

for (j = 0; j < 6; j++) {
dest[j] = 0;
for (i = 0; i < 8; i++) {
dest[j] <<= 1;
dest[j] |= exchange_bit(0, 1);
}
}

/* turn off CS */
exchange_bit(0,0);
}

/*
* Copy and increment ethernet MAC address by a small value.
*
* This is useful for systems where the only one MAC address is stored in
* non-volatile memory for multiple ports.
*/
static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
unsigned int add)
{
int i;

BUG_ON(add >= 256);

for (i = ETH_ALEN; i >= 0; i--) {
dst[i] = src[i] + add;
add = dst[i] < src[i]; /* compute carry */
}

WARN_ON(add);
}

static int __init mv643xx_eth_add_pds(void)
{
unsigned char mac[ETH_ALEN];
int ret;

get_mac(mac);
#ifdef CONFIG_MV643XX_ETH_0
eth_mac_add(eth1_mac_addr, mac, 0);
#endif
#ifdef CONFIG_MV643XX_ETH_1
eth_mac_add(eth1_mac_addr, mac, 1);
#endif
#ifdef CONFIG_MV643XX_ETH_2
eth_mac_add(eth2_mac_addr, mac, 2);
#endif
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));

return ret;
}

device_initcall(mv643xx_eth_add_pds);

#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
Loading

0 comments on commit c836b77

Please sign in to comment.