diff options
Diffstat (limited to 'arch/arm/mach-pxa/zeus.c')
| -rw-r--r-- | arch/arm/mach-pxa/zeus.c | 284 |
1 files changed, 181 insertions, 103 deletions
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 75f2a37f945..205f9bf3821 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -20,32 +20,36 @@ #include <linux/dm9000.h> #include <linux/mmc/host.h> #include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> #include <linux/i2c.h> -#include <linux/i2c/pca953x.h> +#include <linux/i2c/pxa-i2c.h> +#include <linux/platform_data/pca953x.h> #include <linux/apm-emulation.h> +#include <linux/can/platform/mcp251x.h> +#include <linux/regulator/fixed.h> +#include <linux/regulator/machine.h> #include <asm/mach-types.h> +#include <asm/suspend.h> +#include <asm/system_info.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <plat/i2c.h> - -#include <mach/pxa2xx-regs.h> +#include <mach/pxa27x.h> #include <mach/regs-uart.h> -#include <mach/ohci.h> -#include <mach/mmc.h> +#include <linux/platform_data/usb-ohci-pxa27x.h> +#include <linux/platform_data/mmc-pxamci.h> #include <mach/pxa27x-udc.h> #include <mach/udc.h> -#include <mach/pxafb.h> -#include <mach/pxa2xx_spi.h> -#include <mach/mfp-pxa27x.h> +#include <linux/platform_data/video-pxafb.h> #include <mach/pm.h> #include <mach/audio.h> -#include <mach/arcom-pcmcia.h> +#include <linux/platform_data/pcmcia-pxa2xx_viper.h> #include <mach/zeus.h> +#include <mach/smemc.h> #include "generic.h" @@ -81,19 +85,19 @@ static inline int zeus_bit_to_irq(int bit) return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0); } -static void zeus_ack_irq(unsigned int irq) +static void zeus_ack_irq(struct irq_data *d) { - __raw_writew(zeus_irq_to_bitmask(irq), ZEUS_CPLD_ISA_IRQ); + __raw_writew(zeus_irq_to_bitmask(d->irq), ZEUS_CPLD_ISA_IRQ); } -static void zeus_mask_irq(unsigned int irq) +static void zeus_mask_irq(struct irq_data *d) { - zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(irq)); + zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(d->irq)); } -static void zeus_unmask_irq(unsigned int irq) +static void zeus_unmask_irq(struct irq_data *d) { - zeus_irq_enabled_mask |= zeus_irq_to_bitmask(irq); + zeus_irq_enabled_mask |= zeus_irq_to_bitmask(d->irq); } static inline unsigned long zeus_irq_pending(void) @@ -109,7 +113,7 @@ static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc) do { /* we're in a chained irq handler, * so ack the interrupt by hand */ - desc->chip->ack(gpio_to_irq(ZEUS_ISA_GPIO)); + desc->irq_data.chip->irq_ack(&desc->irq_data); if (likely(pending)) { irq = zeus_bit_to_irq(__ffs(pending)); @@ -120,10 +124,10 @@ static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc) } static struct irq_chip zeus_irq_chip = { - .name = "ISA", - .ack = zeus_ack_irq, - .mask = zeus_mask_irq, - .unmask = zeus_unmask_irq, + .name = "ISA", + .irq_ack = zeus_ack_irq, + .irq_mask = zeus_mask_irq, + .irq_unmask = zeus_unmask_irq, }; static void __init zeus_init_irq(void) @@ -135,22 +139,23 @@ static void __init zeus_init_irq(void) /* Peripheral IRQs. It would be nice to move those inside driver configuration, but it is not supported at the moment. */ - set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING); - set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING); - set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING); - set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), IRQ_TYPE_EDGE_FALLING); - set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), + IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING); /* Setup ISA IRQs */ for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) { isa_irq = zeus_bit_to_irq(level); - set_irq_chip(isa_irq, &zeus_irq_chip); - set_irq_handler(isa_irq, handle_edge_irq); + irq_set_chip_and_handler(isa_irq, &zeus_irq_chip, + handle_edge_irq); set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE); } - set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING); - set_irq_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler); + irq_set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING); + irq_set_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler); } @@ -231,7 +236,7 @@ static struct plat_serial8250_port serial_platform_data[] = { /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */ { /* COM1 */ .mapbase = 0x10000000, - .irq = gpio_to_irq(ZEUS_UARTA_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTA_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -240,7 +245,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM2 */ .mapbase = 0x10800000, - .irq = gpio_to_irq(ZEUS_UARTB_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTB_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -249,7 +254,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM3 */ .mapbase = 0x11000000, - .irq = gpio_to_irq(ZEUS_UARTC_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTC_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -258,7 +263,7 @@ static struct plat_serial8250_port serial_platform_data[] = { }, { /* COM4 */ .mapbase = 0x11800000, - .irq = gpio_to_irq(ZEUS_UARTD_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTD_GPIO), .irqflags = IRQF_TRIGGER_RISING, .uartclk = 14745600, .regshift = 1, @@ -319,8 +324,8 @@ static struct resource zeus_dm9k0_resource[] = { .flags = IORESOURCE_MEM }, [2] = { - .start = gpio_to_irq(ZEUS_ETH0_GPIO), - .end = gpio_to_irq(ZEUS_ETH0_GPIO), + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -337,8 +342,8 @@ static struct resource zeus_dm9k1_resource[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = gpio_to_irq(ZEUS_ETH1_GPIO), - .end = gpio_to_irq(ZEUS_ETH1_GPIO), + .start = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), + .end = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, }, }; @@ -387,11 +392,46 @@ static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = { .enable_dma = 1, }; -static struct platform_device pxa2xx_spi_ssp3_device = { - .name = "pxa2xx-spi", - .id = 3, - .dev = { - .platform_data = &pxa2xx_spi_ssp3_master_info, +/* CAN bus on SPI */ +static struct regulator_consumer_supply can_regulator_consumer = + REGULATOR_SUPPLY("vdd", "spi3.0"); + +static struct regulator_init_data can_regulator_init_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = &can_regulator_consumer, + .num_consumer_supplies = 1, +}; + +static struct fixed_voltage_config can_regulator_pdata = { + .supply_name = "CAN_SHDN", + .microvolts = 3300000, + .gpio = ZEUS_CAN_SHDN_GPIO, + .init_data = &can_regulator_init_data, +}; + +static struct platform_device can_regulator_device = { + .name = "reg-fixed-volage", + .id = 0, + .dev = { + .platform_data = &can_regulator_pdata, + }, +}; + +static struct mcp251x_platform_data zeus_mcp2515_pdata = { + .oscillator_frequency = 16*1000*1000, +}; + +static struct spi_board_info zeus_spi_board_info[] = { + [0] = { + .modalias = "mcp2515", + .platform_data = &zeus_mcp2515_pdata, + .irq = PXA_GPIO_TO_IRQ(ZEUS_CAN_GPIO), + .max_speed_hz = 1*1000*1000, + .bus_num = 3, + .mode = SPI_MODE_0, + .chip_select = 0, }, }; @@ -457,15 +497,17 @@ static struct platform_device zeus_pcmcia_device = { }, }; -static struct platform_device *zeus_devices[] __initdata = { - &zeus_serial_device, - &zeus_mtd_devices[0], - &zeus_dm9k0_device, - &zeus_dm9k1_device, - &zeus_sram_device, - &pxa2xx_spi_ssp3_device, - &zeus_leds_device, - &zeus_pcmcia_device, +static struct resource zeus_max6369_resource = { + .start = ZEUS_CPLD_EXTWDOG_PHYS, + .end = ZEUS_CPLD_EXTWDOG_PHYS, + .flags = IORESOURCE_MEM, +}; + +struct platform_device zeus_max6369_device = { + .name = "max6369_wdt", + .id = -1, + .resource = &zeus_max6369_resource, + .num_resources = 1, }; /* AC'97 */ @@ -478,42 +520,50 @@ static pxa2xx_audio_ops_t zeus_ac97_info = { * USB host */ -static int zeus_ohci_init(struct device *dev) -{ - int err; - - /* Switch on port 2. */ - if ((err = gpio_request(ZEUS_USB2_PWREN_GPIO, "USB2_PWREN"))) { - dev_err(dev, "Can't request USB2_PWREN\n"); - return err; - } - - if ((err = gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 1))) { - gpio_free(ZEUS_USB2_PWREN_GPIO); - dev_err(dev, "Can't enable USB2_PWREN\n"); - return err; - } +static struct regulator_consumer_supply zeus_ohci_regulator_supplies[] = { + REGULATOR_SUPPLY("vbus2", "pxa27x-ohci"), +}; - /* Port 2 is shared between host and client interface. */ - UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE; +static struct regulator_init_data zeus_ohci_regulator_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(zeus_ohci_regulator_supplies), + .consumer_supplies = zeus_ohci_regulator_supplies, +}; - return 0; -} +static struct fixed_voltage_config zeus_ohci_regulator_config = { + .supply_name = "vbus2", + .microvolts = 5000000, /* 5.0V */ + .gpio = ZEUS_USB2_PWREN_GPIO, + .enable_high = 1, + .startup_delay = 0, + .init_data = &zeus_ohci_regulator_data, +}; -static void zeus_ohci_exit(struct device *dev) -{ - /* Power-off port 2 */ - gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 0); - gpio_free(ZEUS_USB2_PWREN_GPIO); -} +static struct platform_device zeus_ohci_regulator_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &zeus_ohci_regulator_config, + }, +}; static struct pxaohci_platform_data zeus_ohci_platform_data = { .port_mode = PMM_NPS_MODE, - .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, - .init = zeus_ohci_init, - .exit = zeus_ohci_exit, + /* Clear Power Control Polarity Low and set Power Sense + * Polarity Low. Supply power to USB ports. */ + .flags = ENABLE_PORT_ALL | POWER_SENSE_LOW, }; +static void zeus_register_ohci(void) +{ + /* Port 2 is shared between host and client interface. */ + UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE; + + pxa_set_ohci_info(&zeus_ohci_platform_data); +} + /* * Flat Panel */ @@ -592,7 +642,7 @@ static struct pxafb_mach_info zeus_fb_info = { static struct pxamci_platform_data zeus_mci_platform_data = { .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .detect_delay = HZ/4, + .detect_delay_ms = 250, .gpio_card_detect = ZEUS_MMC_CD_GPIO, .gpio_card_ro = ZEUS_MMC_WP_GPIO, .gpio_card_ro_invert = 1, @@ -621,11 +671,28 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = { .udc_command = zeus_udc_command, }; +static struct platform_device *zeus_devices[] __initdata = { + &zeus_serial_device, + &zeus_mtd_devices[0], + &zeus_dm9k0_device, + &zeus_dm9k1_device, + &zeus_sram_device, + &zeus_leds_device, + &zeus_pcmcia_device, + &zeus_max6369_device, + &can_regulator_device, + &zeus_ohci_regulator_device, +}; + +#ifdef CONFIG_PM static void zeus_power_off(void) { local_irq_disable(); - pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); + cpu_suspend(PWRMODE_DEEPSLEEP, pxa27x_finish_suspend); } +#else +#define zeus_power_off NULL +#endif #ifdef CONFIG_APM_EMULATION static void zeus_get_power_status(struct apm_power_info *info) @@ -698,7 +765,7 @@ static struct i2c_board_info __initdata zeus_i2c_devices[] = { { I2C_BOARD_INFO("pca9535", 0x20), .platform_data = &zeus_pca953x_pdata[2], - .irq = gpio_to_irq(ZEUS_EXTGPIO_GPIO), + .irq = PXA_GPIO_TO_IRQ(ZEUS_EXTGPIO_GPIO), }, { I2C_BOARD_INFO("lm75a", 0x48) }, { I2C_BOARD_INFO("24c01", 0x50) }, @@ -706,6 +773,12 @@ static struct i2c_board_info __initdata zeus_i2c_devices[] = { }; static mfp_cfg_t zeus_pin_config[] __initdata = { + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO15_nCS_1, GPIO78_nCS_2, GPIO80_nCS_4, @@ -731,6 +804,11 @@ static mfp_cfg_t zeus_pin_config[] __initdata = { GPIO104_CIF_DD_2, GPIO105_CIF_DD_1, + GPIO81_SSP3_TXD, + GPIO82_SSP3_RXD, + GPIO83_SSP3_SFRM, + GPIO84_SSP3_SCLK, + GPIO48_nPOE, GPIO49_nPWE, GPIO50_nPIOR, @@ -758,13 +836,16 @@ static mfp_cfg_t zeus_pin_config[] __initdata = { static void __init zeus_init(void) { u16 dm9000_msc = DM9K_MSC_VALUE; + u32 msc0, msc1; system_rev = __raw_readw(ZEUS_CPLD_VERSION); pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); /* Fix timings for dm9000s (CS1/CS2)*/ - MSC0 = (MSC0 & 0xffff) | (dm9000_msc << 16); - MSC1 = (MSC1 & 0xffff0000) | dm9000_msc; + msc0 = (__raw_readl(MSC0) & 0x0000ffff) | (dm9000_msc << 16); + msc1 = (__raw_readl(MSC1) & 0xffff0000) | dm9000_msc; + __raw_writel(msc0, MSC0); + __raw_writel(msc1, MSC1); pm_power_off = zeus_power_off; zeus_setup_apm(); @@ -773,47 +854,43 @@ static void __init zeus_init(void) platform_add_devices(zeus_devices, ARRAY_SIZE(zeus_devices)); - pxa_set_ohci_info(&zeus_ohci_platform_data); + zeus_register_ohci(); if (zeus_setup_fb_gpios()) pr_err("Failed to setup fb gpios\n"); else - set_pxa_fb_info(&zeus_fb_info); + pxa_set_fb_info(NULL, &zeus_fb_info); pxa_set_mci_info(&zeus_mci_platform_data); pxa_set_udc_info(&zeus_udc_info); pxa_set_ac97_info(&zeus_ac97_info); pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices)); + pxa2xx_set_spi_info(3, &pxa2xx_spi_ssp3_master_info); + spi_register_board_info(zeus_spi_board_info, ARRAY_SIZE(zeus_spi_board_info)); } static struct map_desc zeus_io_desc[] __initdata = { { - .virtual = ZEUS_CPLD_VERSION, + .virtual = (unsigned long)ZEUS_CPLD_VERSION, .pfn = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS), .length = 0x1000, .type = MT_DEVICE, }, { - .virtual = ZEUS_CPLD_ISA_IRQ, + .virtual = (unsigned long)ZEUS_CPLD_ISA_IRQ, .pfn = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS), .length = 0x1000, .type = MT_DEVICE, }, { - .virtual = ZEUS_CPLD_CONTROL, + .virtual = (unsigned long)ZEUS_CPLD_CONTROL, .pfn = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS), .length = 0x1000, .type = MT_DEVICE, }, { - .virtual = ZEUS_CPLD_EXTWDOG, - .pfn = __phys_to_pfn(ZEUS_CPLD_EXTWDOG_PHYS), - .length = 0x1000, - .type = MT_DEVICE, - }, - { - .virtual = ZEUS_PC104IO, + .virtual = (unsigned long)ZEUS_PC104IO, .pfn = __phys_to_pfn(ZEUS_PC104IO_PHYS), .length = 0x00800000, .type = MT_DEVICE, @@ -822,7 +899,7 @@ static struct map_desc zeus_io_desc[] __initdata = { static void __init zeus_map_io(void) { - pxa_map_io(); + pxa27x_map_io(); iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc)); @@ -837,14 +914,15 @@ static void __init zeus_map_io(void) PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP; } -MACHINE_START(ARCOM_ZEUS, "Arcom ZEUS") +MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS") /* Maintainer: Marc Zyngier <maz@misterjones.org> */ - .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc), - .boot_params = 0xa0000100, + .atag_offset = 0x100, .map_io = zeus_map_io, + .nr_irqs = ZEUS_NR_IRQS, .init_irq = zeus_init_irq, - .timer = &pxa_timer, + .handle_irq = pxa27x_handle_irq, + .init_time = pxa_timer_init, .init_machine = zeus_init, + .restart = pxa_restart, MACHINE_END |
