/* * linux/arch/sh/boards/mpc1211/setup.c * * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y * */ #include #include #include #include #include #include #include #include #include #include #include /* ALI15X3 SMBus address offsets */ #define SMBHSTSTS (0 + 0x3100) #define SMBHSTCNT (1 + 0x3100) #define SMBHSTSTART (2 + 0x3100) #define SMBHSTCMD (7 + 0x3100) #define SMBHSTADD (3 + 0x3100) #define SMBHSTDAT0 (4 + 0x3100) #define SMBHSTDAT1 (5 + 0x3100) #define SMBBLKDAT (6 + 0x3100) /* Other settings */ #define MAX_TIMEOUT 500 /* times 1/100 sec */ /* ALI15X3 command constants */ #define ALI15X3_ABORT 0x04 #define ALI15X3_T_OUT 0x08 #define ALI15X3_QUICK 0x00 #define ALI15X3_BYTE 0x10 #define ALI15X3_BYTE_DATA 0x20 #define ALI15X3_WORD_DATA 0x30 #define ALI15X3_BLOCK_DATA 0x40 #define ALI15X3_BLOCK_CLR 0x80 /* ALI15X3 status register bits */ #define ALI15X3_STS_IDLE 0x04 #define ALI15X3_STS_BUSY 0x08 #define ALI15X3_STS_DONE 0x10 #define ALI15X3_STS_DEV 0x20 /* device error */ #define ALI15X3_STS_COLL 0x40 /* collision or no response */ #define ALI15X3_STS_TERM 0x80 /* terminated by abort */ #define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ static void __init pci_write_config(unsigned long busNo, unsigned long devNo, unsigned long fncNo, unsigned long cnfAdd, unsigned long cnfData) { ctrl_outl((0x80000000 + ((busNo & 0xff) << 16) + ((devNo & 0x1f) << 11) + ((fncNo & 0x07) << 8) + (cnfAdd & 0xfc)), PCIPAR); ctrl_outl(cnfData, PCIPDR); } /* Initialize IRQ setting */ static unsigned char m_irq_mask = 0xfb; static unsigned char s_irq_mask = 0xff; static void disable_mpc1211_irq(unsigned int irq) { if( irq < 8) { m_irq_mask |= (1 << irq); outb(m_irq_mask,I8259_M_MR); } else { s_irq_mask |= (1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } } static void enable_mpc1211_irq(unsigned int irq) { if( irq < 8) { m_irq_mask &= ~(1 << irq); outb(m_irq_mask,I8259_M_MR); } else { s_irq_mask &= ~(1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } } static inline int mpc1211_irq_real(unsigned int irq) { int value; int irqmask; if ( irq < 8) { irqmask = 1<= MAX_TIMEOUT){ return -1; } outb(((address & 0x7f) << 1), SMBHSTADD); outb(0xc0, SMBHSTCNT); outb(command & 0xff, SMBHSTCMD); outb(no & 0x1f, SMBHSTDAT0); for(i = 1; i <= no; i++) { outb(*p++, SMBBLKDAT); } outb(0xff, SMBHSTSTART); temp = inb(SMBHSTSTS); for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) { delay1000(); temp = inb(SMBHSTSTS); } if (timeout >= MAX_TIMEOUT) { return -2; } if ( temp & ALI15X3_STS_ERR ){ return -3; } return 0; } static struct resource heartbeat_resources[] = { [0] = { .start = 0xa2000000, .end = 0xa2000000 + 8 - 1, .flags = IORESOURCE_MEM, }, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; static struct platform_device *mpc1211_devices[] __initdata = { &heartbeat_device, }; static int __init mpc1211_devices_setup(void) { return platform_add_devices(mpc1211_devices, ARRAY_SIZE(mpc1211_devices)); } __initcall(mpc1211_devices_setup); /* arch/sh/boards/mpc1211/rtc.c */ void mpc1211_time_init(void); static void __init mpc1211_setup(char **cmdline_p) { unsigned char spd_buf[128]; __set_io_port_base(PA_PCI_IO); pci_write_config(0,0,0,0x54, 0xb0b00000); do { outb(ALI15X3_ABORT, SMBHSTCNT); spd_buf[0] = 0x0c; spd_buf[1] = 0x43; spd_buf[2] = 0x7f; spd_buf[3] = 0x03; spd_buf[4] = 0x00; spd_buf[5] = 0x03; spd_buf[6] = 0x00; } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0); board_time_init = mpc1211_time_init; return 0; } /* * The Machine Vector */ static struct sh_machine_vector mv_mpc1211 __initmv = { .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)", .mv_setup = mpc1211_setup, .mv_nr_irqs = 48, .mv_irq_demux = mpc1211_irq_demux, .mv_init_irq = init_mpc1211_IRQ, };