forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: avr32: Fix build failures in board code avr32: Allow selecting multiple pins at once avr32: Minor pm_power_off cleanup avr32: Implement {read,write}[bwl]_be avr32: Replace static clock list with dynamic linked list avr32: Use platform_driver_probe for pdc platform driver avr32: Use platform_driver_probe for pio platform driver avr32: Provide a way to deselect pins in the portmux ngw100: export J15 through sysfs avr32: Allow fine-grained control over LCDC pins avr32: added mem kernel command line option support Add kernel support for oprofile callgraphs on AVR32 avr32: use the new byteorder headers
This commit is contained in:
commit
1a2217a951
@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-gpio.h>
|
||||
@ -193,7 +194,7 @@ static int __init atngw100_init(void)
|
||||
* PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus),
|
||||
* but it's not available off-board.
|
||||
*/
|
||||
at32_select_periph(GPIO_PIN_PB(28), 0, AT32_GPIOF_PULLUP);
|
||||
at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP);
|
||||
at32_select_gpio(i2c_gpio_data.sda_pin,
|
||||
AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
|
||||
at32_select_gpio(i2c_gpio_data.scl_pin,
|
||||
@ -207,6 +208,15 @@ postcore_initcall(atngw100_init);
|
||||
|
||||
static int __init atngw100_arch_init(void)
|
||||
{
|
||||
/* PB30 is the otherwise unused jumper on the mainboard, with an
|
||||
* external pullup; the jumper grounds it. Use it however you
|
||||
* like, including letting U-Boot or Linux tweak boot sequences.
|
||||
*/
|
||||
at32_select_gpio(GPIO_PIN_PB(30), 0);
|
||||
gpio_request(GPIO_PIN_PB(30), "j15");
|
||||
gpio_direction_input(GPIO_PIN_PB(30));
|
||||
gpio_export(GPIO_PIN_PB(30), false);
|
||||
|
||||
/* set_irq_type() after the arch_initcall for EIC has run, and
|
||||
* before the I2C subsystem could try using this IRQ.
|
||||
*/
|
||||
|
@ -232,7 +232,7 @@ static void __init atstk1002_setup_extdac(void)
|
||||
goto err_set_clk;
|
||||
}
|
||||
|
||||
at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
|
||||
at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
|
||||
at73c213_data.dac_clk = gclk;
|
||||
|
||||
err_set_clk:
|
||||
@ -330,13 +330,14 @@ static int __init atstk1002_init(void)
|
||||
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
|
||||
#endif
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
|
||||
at32_add_device_mci(0, &mci0_pdata);
|
||||
at32_add_device_mci(0, &mci0_data);
|
||||
#endif
|
||||
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
|
||||
set_hw_addr(at32_add_device_eth(1, ð_data[1]));
|
||||
#else
|
||||
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
|
||||
fbmem_start, fbmem_size, 0);
|
||||
fbmem_start, fbmem_size,
|
||||
ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL);
|
||||
#endif
|
||||
at32_add_device_usba(0, NULL);
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/atmel-mci.h>
|
||||
|
||||
#include <mach/at32ap700x.h>
|
||||
#include <mach/board.h>
|
||||
@ -94,7 +95,7 @@ static void __init atstk1003_setup_extdac(void)
|
||||
goto err_set_clk;
|
||||
}
|
||||
|
||||
at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
|
||||
at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
|
||||
at73c213_data.dac_clk = gclk;
|
||||
|
||||
err_set_clk:
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/atmel-mci.h>
|
||||
|
||||
#include <mach/at32ap700x.h>
|
||||
#include <mach/board.h>
|
||||
@ -99,7 +100,7 @@ static void __init atstk1004_setup_extdac(void)
|
||||
goto err_set_clk;
|
||||
}
|
||||
|
||||
at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
|
||||
at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
|
||||
at73c213_data.dac_clk = gclk;
|
||||
|
||||
err_set_clk:
|
||||
@ -150,7 +151,8 @@ static int __init atstk1004_init(void)
|
||||
at32_add_device_mci(0, &mci0_data);
|
||||
#endif
|
||||
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
|
||||
fbmem_start, fbmem_size, 0);
|
||||
fbmem_start, fbmem_size,
|
||||
ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL);
|
||||
at32_add_device_usba(0, NULL);
|
||||
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
|
||||
at32_add_device_ssc(0, ATMEL_SSC_TX);
|
||||
|
@ -7,6 +7,9 @@
|
||||
#include <asm/types.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#define __BIG_ENDIAN
|
||||
#define __SWAB_64_THRU_32__
|
||||
|
||||
#ifdef __CHECKER__
|
||||
extern unsigned long __builtin_bswap_32(unsigned long x);
|
||||
extern unsigned short __builtin_bswap_16(unsigned short x);
|
||||
@ -17,15 +20,18 @@ extern unsigned short __builtin_bswap_16(unsigned short x);
|
||||
* the result.
|
||||
*/
|
||||
#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2)
|
||||
#define __arch__swab32(x) __builtin_bswap_32(x)
|
||||
#define __arch__swab16(x) __builtin_bswap_16(x)
|
||||
static inline __attribute_const__ __u16 __arch_swab16(__u16 val)
|
||||
{
|
||||
return __builtin_bswap_16(val);
|
||||
}
|
||||
#define __arch_swab16 __arch_swab16
|
||||
|
||||
static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
|
||||
{
|
||||
return __builtin_bswap_32(val);
|
||||
}
|
||||
#define __arch_swab32 __arch_swab32
|
||||
#endif
|
||||
|
||||
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||
# define __BYTEORDER_HAS_U64__
|
||||
# define __SWAB_64_THRU_32__
|
||||
#endif
|
||||
|
||||
#include <linux/byteorder/big_endian.h>
|
||||
|
||||
#include <linux/byteorder.h>
|
||||
#endif /* __ASM_AVR32_BYTEORDER_H */
|
||||
|
@ -160,6 +160,14 @@ BUILDIO_IOPORT(l, u32)
|
||||
#define readw_relaxed readw
|
||||
#define readl_relaxed readl
|
||||
|
||||
#define readb_be __raw_readb
|
||||
#define readw_be __raw_readw
|
||||
#define readl_be __raw_readl
|
||||
|
||||
#define writeb_be __raw_writeb
|
||||
#define writew_be __raw_writew
|
||||
#define writel_be __raw_writel
|
||||
|
||||
#define __BUILD_MEMORY_STRING(bwl, type) \
|
||||
static inline void writes##bwl(volatile void __iomem *addr, \
|
||||
const void *data, unsigned int count) \
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/tick.h>
|
||||
@ -20,7 +21,7 @@
|
||||
|
||||
#include <mach/pm.h>
|
||||
|
||||
void (*pm_power_off)(void) = NULL;
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
/*
|
||||
|
@ -283,6 +283,25 @@ static int __init early_parse_fbmem(char *p)
|
||||
}
|
||||
early_param("fbmem", early_parse_fbmem);
|
||||
|
||||
/*
|
||||
* Pick out the memory size. We look for mem=size@start,
|
||||
* where start and size are "size[KkMmGg]"
|
||||
*/
|
||||
static int __init early_mem(char *p)
|
||||
{
|
||||
resource_size_t size, start;
|
||||
|
||||
start = system_ram->start;
|
||||
size = memparse(p, &p);
|
||||
if (*p == '@')
|
||||
start = memparse(p + 1, &p);
|
||||
|
||||
system_ram->start = start;
|
||||
system_ram->end = system_ram->start + size - 1;
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", early_mem);
|
||||
|
||||
static int __init parse_tag_core(struct tag *tag)
|
||||
{
|
||||
if (tag->hdr.size > 2) {
|
||||
|
@ -82,8 +82,9 @@ static struct platform_device _name##_id##_device = { \
|
||||
.num_resources = ARRAY_SIZE(_name##_id##_resource), \
|
||||
}
|
||||
|
||||
#define select_peripheral(pin, periph, flags) \
|
||||
at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags)
|
||||
#define select_peripheral(port, pin_mask, periph, flags) \
|
||||
at32_select_periph(GPIO_##port##_BASE, pin_mask, \
|
||||
GPIO_##periph, flags)
|
||||
|
||||
#define DEV_CLK(_name, devname, bus, _index) \
|
||||
static struct clk devname##_##_name = { \
|
||||
@ -871,6 +872,7 @@ static struct clk atmel_psif1_pclk = {
|
||||
struct platform_device *__init at32_add_device_psif(unsigned int id)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
if (!(id == 0 || id == 1))
|
||||
return NULL;
|
||||
@ -881,20 +883,22 @@ struct platform_device *__init at32_add_device_psif(unsigned int id)
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
pin_mask = (1 << 8) | (1 << 9); /* CLOCK & DATA */
|
||||
|
||||
if (platform_device_add_resources(pdev, atmel_psif0_resource,
|
||||
ARRAY_SIZE(atmel_psif0_resource)))
|
||||
goto err_add_resources;
|
||||
atmel_psif0_pclk.dev = &pdev->dev;
|
||||
select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */
|
||||
select_peripheral(PA(9), PERIPH_A, 0); /* DATA */
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
break;
|
||||
case 1:
|
||||
pin_mask = (1 << 11) | (1 << 12); /* CLOCK & DATA */
|
||||
|
||||
if (platform_device_add_resources(pdev, atmel_psif1_resource,
|
||||
ARRAY_SIZE(atmel_psif1_resource)))
|
||||
goto err_add_resources;
|
||||
atmel_psif1_pclk.dev = &pdev->dev;
|
||||
select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */
|
||||
select_peripheral(PB(12), PERIPH_A, 0); /* DATA */
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
@ -958,26 +962,30 @@ DEV_CLK(usart, atmel_usart3, pba, 6);
|
||||
|
||||
static inline void configure_usart0_pins(void)
|
||||
{
|
||||
select_peripheral(PA(8), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PA(9), PERIPH_B, 0); /* TXD */
|
||||
u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
|
||||
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
|
||||
}
|
||||
|
||||
static inline void configure_usart1_pins(void)
|
||||
{
|
||||
select_peripheral(PA(17), PERIPH_A, 0); /* RXD */
|
||||
select_peripheral(PA(18), PERIPH_A, 0); /* TXD */
|
||||
u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
|
||||
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
}
|
||||
|
||||
static inline void configure_usart2_pins(void)
|
||||
{
|
||||
select_peripheral(PB(26), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PB(27), PERIPH_B, 0); /* TXD */
|
||||
u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
|
||||
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
|
||||
}
|
||||
|
||||
static inline void configure_usart3_pins(void)
|
||||
{
|
||||
select_peripheral(PB(18), PERIPH_B, 0); /* RXD */
|
||||
select_peripheral(PB(17), PERIPH_B, 0); /* TXD */
|
||||
u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
|
||||
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
|
||||
}
|
||||
|
||||
static struct platform_device *__initdata at32_usarts[4];
|
||||
@ -1057,59 +1065,69 @@ struct platform_device *__init
|
||||
at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
pdev = &macb0_device;
|
||||
|
||||
select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */
|
||||
select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */
|
||||
select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */
|
||||
select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */
|
||||
select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */
|
||||
select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */
|
||||
select_peripheral(PC(13), PERIPH_A, 0); /* RXER */
|
||||
select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */
|
||||
select_peripheral(PC(16), PERIPH_A, 0); /* MDC */
|
||||
select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */
|
||||
pin_mask = (1 << 3); /* TXD0 */
|
||||
pin_mask |= (1 << 4); /* TXD1 */
|
||||
pin_mask |= (1 << 7); /* TXEN */
|
||||
pin_mask |= (1 << 8); /* TXCK */
|
||||
pin_mask |= (1 << 9); /* RXD0 */
|
||||
pin_mask |= (1 << 10); /* RXD1 */
|
||||
pin_mask |= (1 << 13); /* RXER */
|
||||
pin_mask |= (1 << 15); /* RXDV */
|
||||
pin_mask |= (1 << 16); /* MDC */
|
||||
pin_mask |= (1 << 17); /* MDIO */
|
||||
|
||||
if (!data->is_rmii) {
|
||||
select_peripheral(PC(0), PERIPH_A, 0); /* COL */
|
||||
select_peripheral(PC(1), PERIPH_A, 0); /* CRS */
|
||||
select_peripheral(PC(2), PERIPH_A, 0); /* TXER */
|
||||
select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */
|
||||
select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */
|
||||
select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */
|
||||
select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */
|
||||
select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */
|
||||
select_peripheral(PC(18), PERIPH_A, 0); /* SPD */
|
||||
pin_mask |= (1 << 0); /* COL */
|
||||
pin_mask |= (1 << 1); /* CRS */
|
||||
pin_mask |= (1 << 2); /* TXER */
|
||||
pin_mask |= (1 << 5); /* TXD2 */
|
||||
pin_mask |= (1 << 6); /* TXD3 */
|
||||
pin_mask |= (1 << 11); /* RXD2 */
|
||||
pin_mask |= (1 << 12); /* RXD3 */
|
||||
pin_mask |= (1 << 14); /* RXCK */
|
||||
pin_mask |= (1 << 18); /* SPD */
|
||||
}
|
||||
|
||||
select_peripheral(PIOC, pin_mask, PERIPH_A, 0);
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pdev = &macb1_device;
|
||||
|
||||
select_peripheral(PD(13), PERIPH_B, 0); /* TXD0 */
|
||||
select_peripheral(PD(14), PERIPH_B, 0); /* TXD1 */
|
||||
select_peripheral(PD(11), PERIPH_B, 0); /* TXEN */
|
||||
select_peripheral(PD(12), PERIPH_B, 0); /* TXCK */
|
||||
select_peripheral(PD(10), PERIPH_B, 0); /* RXD0 */
|
||||
select_peripheral(PD(6), PERIPH_B, 0); /* RXD1 */
|
||||
select_peripheral(PD(5), PERIPH_B, 0); /* RXER */
|
||||
select_peripheral(PD(4), PERIPH_B, 0); /* RXDV */
|
||||
select_peripheral(PD(3), PERIPH_B, 0); /* MDC */
|
||||
select_peripheral(PD(2), PERIPH_B, 0); /* MDIO */
|
||||
pin_mask = (1 << 13); /* TXD0 */
|
||||
pin_mask |= (1 << 14); /* TXD1 */
|
||||
pin_mask |= (1 << 11); /* TXEN */
|
||||
pin_mask |= (1 << 12); /* TXCK */
|
||||
pin_mask |= (1 << 10); /* RXD0 */
|
||||
pin_mask |= (1 << 6); /* RXD1 */
|
||||
pin_mask |= (1 << 5); /* RXER */
|
||||
pin_mask |= (1 << 4); /* RXDV */
|
||||
pin_mask |= (1 << 3); /* MDC */
|
||||
pin_mask |= (1 << 2); /* MDIO */
|
||||
|
||||
if (!data->is_rmii)
|
||||
pin_mask |= (1 << 15); /* SPD */
|
||||
|
||||
select_peripheral(PIOD, pin_mask, PERIPH_B, 0);
|
||||
|
||||
if (!data->is_rmii) {
|
||||
select_peripheral(PC(19), PERIPH_B, 0); /* COL */
|
||||
select_peripheral(PC(23), PERIPH_B, 0); /* CRS */
|
||||
select_peripheral(PC(26), PERIPH_B, 0); /* TXER */
|
||||
select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */
|
||||
select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */
|
||||
select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */
|
||||
select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */
|
||||
select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */
|
||||
select_peripheral(PD(15), PERIPH_B, 0); /* SPD */
|
||||
pin_mask = (1 << 19); /* COL */
|
||||
pin_mask |= (1 << 23); /* CRS */
|
||||
pin_mask |= (1 << 26); /* TXER */
|
||||
pin_mask |= (1 << 27); /* TXD2 */
|
||||
pin_mask |= (1 << 28); /* TXD3 */
|
||||
pin_mask |= (1 << 29); /* RXD2 */
|
||||
pin_mask |= (1 << 30); /* RXD3 */
|
||||
pin_mask |= (1 << 24); /* RXCK */
|
||||
|
||||
select_peripheral(PIOC, pin_mask, PERIPH_B, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1177,23 +1195,28 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
|
||||
{ GPIO_PIN_PB(2), GPIO_PIN_PB(3),
|
||||
GPIO_PIN_PB(4), GPIO_PIN_PA(27), };
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
pdev = &atmel_spi0_device;
|
||||
pin_mask = (1 << 1) | (1 << 2); /* MOSI & SCK */
|
||||
|
||||
/* pullup MISO so a level is always defined */
|
||||
select_peripheral(PA(0), PERIPH_A, AT32_GPIOF_PULLUP);
|
||||
select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */
|
||||
select_peripheral(PA(2), PERIPH_A, 0); /* SCK */
|
||||
select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP);
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
|
||||
at32_spi_setup_slaves(0, b, n, spi0_pins);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pdev = &atmel_spi1_device;
|
||||
pin_mask = (1 << 1) | (1 << 5); /* MOSI */
|
||||
|
||||
/* pullup MISO so a level is always defined */
|
||||
select_peripheral(PB(0), PERIPH_B, AT32_GPIOF_PULLUP);
|
||||
select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */
|
||||
select_peripheral(PB(5), PERIPH_B, 0); /* SCK */
|
||||
select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP);
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
|
||||
|
||||
at32_spi_setup_slaves(1, b, n, spi1_pins);
|
||||
break;
|
||||
|
||||
@ -1226,6 +1249,7 @@ struct platform_device *__init at32_add_device_twi(unsigned int id,
|
||||
unsigned int n)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
@ -1238,8 +1262,9 @@ struct platform_device *__init at32_add_device_twi(unsigned int id,
|
||||
ARRAY_SIZE(atmel_twi0_resource)))
|
||||
goto err_add_resources;
|
||||
|
||||
select_peripheral(PA(6), PERIPH_A, 0); /* SDA */
|
||||
select_peripheral(PA(7), PERIPH_A, 0); /* SDL */
|
||||
pin_mask = (1 << 6) | (1 << 7); /* SDA & SDL */
|
||||
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
|
||||
atmel_twi0_pclk.dev = &pdev->dev;
|
||||
|
||||
@ -1274,6 +1299,8 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct dw_dma_slave *dws;
|
||||
u32 pioa_mask;
|
||||
u32 piob_mask;
|
||||
|
||||
if (id != 0 || !data)
|
||||
return NULL;
|
||||
@ -1311,17 +1338,17 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
||||
goto fail;
|
||||
|
||||
/* CLK line is common to both slots */
|
||||
select_peripheral(PA(10), PERIPH_A, 0);
|
||||
pioa_mask = 1 << 10;
|
||||
|
||||
switch (data->slot[0].bus_width) {
|
||||
case 4:
|
||||
select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
|
||||
select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
|
||||
select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
|
||||
pioa_mask |= 1 << 13; /* DATA1 */
|
||||
pioa_mask |= 1 << 14; /* DATA2 */
|
||||
pioa_mask |= 1 << 15; /* DATA3 */
|
||||
/* fall through */
|
||||
case 1:
|
||||
select_peripheral(PA(11), PERIPH_A, 0); /* CMD */
|
||||
select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
|
||||
pioa_mask |= 1 << 11; /* CMD */
|
||||
pioa_mask |= 1 << 12; /* DATA0 */
|
||||
|
||||
if (gpio_is_valid(data->slot[0].detect_pin))
|
||||
at32_select_gpio(data->slot[0].detect_pin, 0);
|
||||
@ -1335,15 +1362,19 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
select_peripheral(PIOA, pioa_mask, PERIPH_A, 0);
|
||||
piob_mask = 0;
|
||||
|
||||
switch (data->slot[1].bus_width) {
|
||||
case 4:
|
||||
select_peripheral(PB(8), PERIPH_B, 0); /* DATA1 */
|
||||
select_peripheral(PB(9), PERIPH_B, 0); /* DATA2 */
|
||||
select_peripheral(PB(10), PERIPH_B, 0); /* DATA3 */
|
||||
piob_mask |= 1 << 8; /* DATA1 */
|
||||
piob_mask |= 1 << 9; /* DATA2 */
|
||||
piob_mask |= 1 << 10; /* DATA3 */
|
||||
/* fall through */
|
||||
case 1:
|
||||
select_peripheral(PB(6), PERIPH_B, 0); /* CMD */
|
||||
select_peripheral(PB(7), PERIPH_B, 0); /* DATA0 */
|
||||
piob_mask |= 1 << 6; /* CMD */
|
||||
piob_mask |= 1 << 7; /* DATA0 */
|
||||
select_peripheral(PIOB, piob_mask, PERIPH_B, 0);
|
||||
|
||||
if (gpio_is_valid(data->slot[1].detect_pin))
|
||||
at32_select_gpio(data->slot[1].detect_pin, 0);
|
||||
@ -1405,13 +1436,14 @@ static struct clk atmel_lcdfb0_pixclk = {
|
||||
struct platform_device *__init
|
||||
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
unsigned long fbmem_start, unsigned long fbmem_len,
|
||||
unsigned int pin_config)
|
||||
u64 pin_mask)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct atmel_lcdfb_info *info;
|
||||
struct fb_monspecs *monspecs;
|
||||
struct fb_videomode *modedb;
|
||||
unsigned int modedb_size;
|
||||
u32 portc_mask, portd_mask, porte_mask;
|
||||
|
||||
/*
|
||||
* Do a deep copy of the fb data, monspecs and modedb. Make
|
||||
@ -1433,76 +1465,21 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
case 0:
|
||||
pdev = &atmel_lcdfb0_device;
|
||||
|
||||
switch (pin_config) {
|
||||
case 0:
|
||||
select_peripheral(PC(19), PERIPH_A, 0); /* CC */
|
||||
select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
|
||||
select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
|
||||
select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */
|
||||
select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */
|
||||
select_peripheral(PC(24), PERIPH_A, 0); /* MODE */
|
||||
select_peripheral(PC(25), PERIPH_A, 0); /* PWR */
|
||||
select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */
|
||||
select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */
|
||||
select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */
|
||||
select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */
|
||||
select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */
|
||||
select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */
|
||||
select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */
|
||||
select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */
|
||||
select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */
|
||||
select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */
|
||||
select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */
|
||||
select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */
|
||||
select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */
|
||||
select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */
|
||||
select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */
|
||||
select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */
|
||||
select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */
|
||||
select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */
|
||||
select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */
|
||||
select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */
|
||||
select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */
|
||||
select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */
|
||||
select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
|
||||
select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
|
||||
break;
|
||||
case 1:
|
||||
select_peripheral(PE(0), PERIPH_B, 0); /* CC */
|
||||
select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */
|
||||
select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */
|
||||
select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */
|
||||
select_peripheral(PE(1), PERIPH_B, 0); /* DVAL */
|
||||
select_peripheral(PE(2), PERIPH_B, 0); /* MODE */
|
||||
select_peripheral(PC(25), PERIPH_A, 0); /* PWR */
|
||||
select_peripheral(PE(3), PERIPH_B, 0); /* DATA0 */
|
||||
select_peripheral(PE(4), PERIPH_B, 0); /* DATA1 */
|
||||
select_peripheral(PE(5), PERIPH_B, 0); /* DATA2 */
|
||||
select_peripheral(PE(6), PERIPH_B, 0); /* DATA3 */
|
||||
select_peripheral(PE(7), PERIPH_B, 0); /* DATA4 */
|
||||
select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */
|
||||
select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */
|
||||
select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */
|
||||
select_peripheral(PE(8), PERIPH_B, 0); /* DATA8 */
|
||||
select_peripheral(PE(9), PERIPH_B, 0); /* DATA9 */
|
||||
select_peripheral(PE(10), PERIPH_B, 0); /* DATA10 */
|
||||
select_peripheral(PE(11), PERIPH_B, 0); /* DATA11 */
|
||||
select_peripheral(PE(12), PERIPH_B, 0); /* DATA12 */
|
||||
select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */
|
||||
select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */
|
||||
select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */
|
||||
select_peripheral(PE(13), PERIPH_B, 0); /* DATA16 */
|
||||
select_peripheral(PE(14), PERIPH_B, 0); /* DATA17 */
|
||||
select_peripheral(PE(15), PERIPH_B, 0); /* DATA18 */
|
||||
select_peripheral(PE(16), PERIPH_B, 0); /* DATA19 */
|
||||
select_peripheral(PE(17), PERIPH_B, 0); /* DATA20 */
|
||||
select_peripheral(PE(18), PERIPH_B, 0); /* DATA21 */
|
||||
select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
|
||||
select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
|
||||
break;
|
||||
default:
|
||||
goto err_invalid_id;
|
||||
}
|
||||
if (pin_mask == 0ULL)
|
||||
/* Default to "full" lcdc control signals and 24bit */
|
||||
pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL;
|
||||
|
||||
/* LCDC on port C */
|
||||
portc_mask = (pin_mask & 0xfff80000) >> 19;
|
||||
select_peripheral(PIOC, portc_mask, PERIPH_A, 0);
|
||||
|
||||
/* LCDC on port D */
|
||||
portd_mask = pin_mask & 0x0003ffff;
|
||||
select_peripheral(PIOD, portd_mask, PERIPH_A, 0);
|
||||
|
||||
/* LCDC on port E */
|
||||
porte_mask = (pin_mask >> 32) & 0x0007ffff;
|
||||
select_peripheral(PIOE, porte_mask, PERIPH_B, 0);
|
||||
|
||||
clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
|
||||
clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
|
||||
@ -1551,6 +1528,7 @@ static struct clk atmel_pwm0_mck = {
|
||||
struct platform_device *__init at32_add_device_pwm(u32 mask)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
if (!mask)
|
||||
return NULL;
|
||||
@ -1566,14 +1544,21 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
|
||||
if (platform_device_add_data(pdev, &mask, sizeof(mask)))
|
||||
goto out_free_pdev;
|
||||
|
||||
pin_mask = 0;
|
||||
if (mask & (1 << 0))
|
||||
select_peripheral(PA(28), PERIPH_A, 0);
|
||||
pin_mask |= (1 << 28);
|
||||
if (mask & (1 << 1))
|
||||
select_peripheral(PA(29), PERIPH_A, 0);
|
||||
pin_mask |= (1 << 29);
|
||||
if (pin_mask > 0)
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
|
||||
pin_mask = 0;
|
||||
if (mask & (1 << 2))
|
||||
select_peripheral(PA(21), PERIPH_B, 0);
|
||||
pin_mask |= (1 << 21);
|
||||
if (mask & (1 << 3))
|
||||
select_peripheral(PA(22), PERIPH_B, 0);
|
||||
pin_mask |= (1 << 22);
|
||||
if (pin_mask > 0)
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
|
||||
|
||||
atmel_pwm0_mck.dev = &pdev->dev;
|
||||
|
||||
@ -1614,52 +1599,65 @@ struct platform_device *__init
|
||||
at32_add_device_ssc(unsigned int id, unsigned int flags)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask = 0;
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
pdev = &ssc0_device;
|
||||
if (flags & ATMEL_SSC_RF)
|
||||
select_peripheral(PA(21), PERIPH_A, 0); /* RF */
|
||||
pin_mask |= (1 << 21); /* RF */
|
||||
if (flags & ATMEL_SSC_RK)
|
||||
select_peripheral(PA(22), PERIPH_A, 0); /* RK */
|
||||
pin_mask |= (1 << 22); /* RK */
|
||||
if (flags & ATMEL_SSC_TK)
|
||||
select_peripheral(PA(23), PERIPH_A, 0); /* TK */
|
||||
pin_mask |= (1 << 23); /* TK */
|
||||
if (flags & ATMEL_SSC_TF)
|
||||
select_peripheral(PA(24), PERIPH_A, 0); /* TF */
|
||||
pin_mask |= (1 << 24); /* TF */
|
||||
if (flags & ATMEL_SSC_TD)
|
||||
select_peripheral(PA(25), PERIPH_A, 0); /* TD */
|
||||
pin_mask |= (1 << 25); /* TD */
|
||||
if (flags & ATMEL_SSC_RD)
|
||||
select_peripheral(PA(26), PERIPH_A, 0); /* RD */
|
||||
pin_mask |= (1 << 26); /* RD */
|
||||
|
||||
if (pin_mask > 0)
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
pdev = &ssc1_device;
|
||||
if (flags & ATMEL_SSC_RF)
|
||||
select_peripheral(PA(0), PERIPH_B, 0); /* RF */
|
||||
pin_mask |= (1 << 0); /* RF */
|
||||
if (flags & ATMEL_SSC_RK)
|
||||
select_peripheral(PA(1), PERIPH_B, 0); /* RK */
|
||||
pin_mask |= (1 << 1); /* RK */
|
||||
if (flags & ATMEL_SSC_TK)
|
||||
select_peripheral(PA(2), PERIPH_B, 0); /* TK */
|
||||
pin_mask |= (1 << 2); /* TK */
|
||||
if (flags & ATMEL_SSC_TF)
|
||||
select_peripheral(PA(3), PERIPH_B, 0); /* TF */
|
||||
pin_mask |= (1 << 3); /* TF */
|
||||
if (flags & ATMEL_SSC_TD)
|
||||
select_peripheral(PA(4), PERIPH_B, 0); /* TD */
|
||||
pin_mask |= (1 << 4); /* TD */
|
||||
if (flags & ATMEL_SSC_RD)
|
||||
select_peripheral(PA(5), PERIPH_B, 0); /* RD */
|
||||
pin_mask |= (1 << 5); /* RD */
|
||||
|
||||
if (pin_mask > 0)
|
||||
select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
|
||||
|
||||
break;
|
||||
case 2:
|
||||
pdev = &ssc2_device;
|
||||
if (flags & ATMEL_SSC_TD)
|
||||
select_peripheral(PB(13), PERIPH_A, 0); /* TD */
|
||||
pin_mask |= (1 << 13); /* TD */
|
||||
if (flags & ATMEL_SSC_RD)
|
||||
select_peripheral(PB(14), PERIPH_A, 0); /* RD */
|
||||
pin_mask |= (1 << 14); /* RD */
|
||||
if (flags & ATMEL_SSC_TK)
|
||||
select_peripheral(PB(15), PERIPH_A, 0); /* TK */
|
||||
pin_mask |= (1 << 15); /* TK */
|
||||
if (flags & ATMEL_SSC_TF)
|
||||
select_peripheral(PB(16), PERIPH_A, 0); /* TF */
|
||||
pin_mask |= (1 << 16); /* TF */
|
||||
if (flags & ATMEL_SSC_RF)
|
||||
select_peripheral(PB(17), PERIPH_A, 0); /* RF */
|
||||
pin_mask |= (1 << 17); /* RF */
|
||||
if (flags & ATMEL_SSC_RK)
|
||||
select_peripheral(PB(18), PERIPH_A, 0); /* RK */
|
||||
pin_mask |= (1 << 18); /* RK */
|
||||
|
||||
if (pin_mask > 0)
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
|
||||
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
@ -1797,14 +1795,15 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
|
||||
unsigned int cs, unsigned int extint)
|
||||
{
|
||||
static unsigned int extint_pin_map[4] __initdata = {
|
||||
GPIO_PIN_PB(25),
|
||||
GPIO_PIN_PB(26),
|
||||
GPIO_PIN_PB(27),
|
||||
GPIO_PIN_PB(28),
|
||||
(1 << 25),
|
||||
(1 << 26),
|
||||
(1 << 27),
|
||||
(1 << 28),
|
||||
};
|
||||
static bool common_pins_initialized __initdata = false;
|
||||
unsigned int extint_pin;
|
||||
int ret;
|
||||
u32 pin_mask;
|
||||
|
||||
if (extint >= ARRAY_SIZE(extint_pin_map))
|
||||
return -EINVAL;
|
||||
@ -1818,7 +1817,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */
|
||||
/* NCS4 -> OE_N */
|
||||
select_peripheral(PIOE, (1 << 21), PERIPH_A, 0);
|
||||
hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE);
|
||||
break;
|
||||
case 5:
|
||||
@ -1828,7 +1828,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
select_peripheral(PE(22), PERIPH_A, 0); /* NCS5 -> OE_N */
|
||||
/* NCS5 -> OE_N */
|
||||
select_peripheral(PIOE, (1 << 22), PERIPH_A, 0);
|
||||
hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE);
|
||||
break;
|
||||
default:
|
||||
@ -1836,14 +1837,17 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
|
||||
}
|
||||
|
||||
if (!common_pins_initialized) {
|
||||
select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */
|
||||
select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */
|
||||
select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */
|
||||
select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */
|
||||
pin_mask = (1 << 19); /* CFCE1 -> CS0_N */
|
||||
pin_mask |= (1 << 20); /* CFCE2 -> CS1_N */
|
||||
pin_mask |= (1 << 23); /* CFRNW -> DIR */
|
||||
pin_mask |= (1 << 24); /* NWAIT <- IORDY */
|
||||
|
||||
select_peripheral(PIOE, pin_mask, PERIPH_A, 0);
|
||||
|
||||
common_pins_initialized = true;
|
||||
}
|
||||
|
||||
at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
|
||||
select_peripheral(PIOB, extint_pin, PERIPH_A, AT32_GPIOF_DEGLITCH);
|
||||
|
||||
pdev->resource[1].start = EIM_IRQ_BASE + extint;
|
||||
pdev->resource[1].end = pdev->resource[1].start;
|
||||
@ -1982,6 +1986,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct ac97c_platform_data _data;
|
||||
u32 pin_mask;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
@ -2008,10 +2013,10 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
|
||||
sizeof(struct ac97c_platform_data)))
|
||||
goto fail;
|
||||
|
||||
select_peripheral(PB(20), PERIPH_B, 0); /* SDO */
|
||||
select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */
|
||||
select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */
|
||||
select_peripheral(PB(23), PERIPH_B, 0); /* SDI */
|
||||
pin_mask = (1 << 20) | (1 << 21); /* SDO & SYNC */
|
||||
pin_mask |= (1 << 22) | (1 << 23); /* SCLK & SDI */
|
||||
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
|
||||
|
||||
/* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
|
||||
if (data->reset_pin != GPIO_PIN_NONE)
|
||||
@ -2053,6 +2058,7 @@ static struct clk abdac0_sample_clk = {
|
||||
struct platform_device *__init at32_add_device_abdac(unsigned int id)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
u32 pin_mask;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
@ -2065,10 +2071,10 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id)
|
||||
ARRAY_SIZE(abdac0_resource)))
|
||||
goto err_add_resources;
|
||||
|
||||
select_peripheral(PB(20), PERIPH_A, 0); /* DATA1 */
|
||||
select_peripheral(PB(21), PERIPH_A, 0); /* DATA0 */
|
||||
select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1 */
|
||||
select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0 */
|
||||
pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */
|
||||
pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */
|
||||
|
||||
select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
|
||||
|
||||
abdac0_pclk.dev = &pdev->dev;
|
||||
abdac0_sample_clk.dev = &pdev->dev;
|
||||
@ -2125,7 +2131,7 @@ static struct clk gclk4 = {
|
||||
.index = 4,
|
||||
};
|
||||
|
||||
struct clk *at32_clock_list[] = {
|
||||
static __initdata struct clk *init_clocks[] = {
|
||||
&osc32k,
|
||||
&osc0,
|
||||
&osc1,
|
||||
@ -2189,7 +2195,6 @@ struct clk *at32_clock_list[] = {
|
||||
&gclk3,
|
||||
&gclk4,
|
||||
};
|
||||
unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
|
||||
|
||||
void __init setup_platform(void)
|
||||
{
|
||||
@ -2220,14 +2225,19 @@ void __init setup_platform(void)
|
||||
genclk_init_parent(&abdac0_sample_clk);
|
||||
|
||||
/*
|
||||
* Turn on all clocks that have at least one user already, and
|
||||
* turn off everything else. We only do this for module
|
||||
* clocks, and even though it isn't particularly pretty to
|
||||
* check the address of the mode function, it should do the
|
||||
* trick...
|
||||
* Build initial dynamic clock list by registering all clocks
|
||||
* from the array.
|
||||
* At the same time, turn on all clocks that have at least one
|
||||
* user already, and turn off everything else. We only do this
|
||||
* for module clocks, and even though it isn't particularly
|
||||
* pretty to check the address of the mode function, it should
|
||||
* do the trick...
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
|
||||
struct clk *clk = at32_clock_list[i];
|
||||
for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
|
||||
struct clk *clk = init_clocks[i];
|
||||
|
||||
/* first, register clock */
|
||||
at32_clk_register(clk);
|
||||
|
||||
if (clk->users == 0)
|
||||
continue;
|
||||
|
@ -15,24 +15,40 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <mach/chip.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
/* at32 clock list */
|
||||
static LIST_HEAD(at32_clock_list);
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
static DEFINE_SPINLOCK(clk_list_lock);
|
||||
|
||||
void at32_clk_register(struct clk *clk)
|
||||
{
|
||||
spin_lock(&clk_list_lock);
|
||||
/* add the new item to the end of the list */
|
||||
list_add_tail(&clk->list, &at32_clock_list);
|
||||
spin_unlock(&clk_list_lock);
|
||||
}
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
int i;
|
||||
struct clk *clk;
|
||||
|
||||
for (i = 0; i < at32_nr_clocks; i++) {
|
||||
struct clk *clk = at32_clock_list[i];
|
||||
spin_lock(&clk_list_lock);
|
||||
|
||||
if (clk->dev == dev && strcmp(id, clk->name) == 0)
|
||||
list_for_each_entry(clk, &at32_clock_list, list) {
|
||||
if (clk->dev == dev && strcmp(id, clk->name) == 0) {
|
||||
spin_unlock(&clk_list_lock);
|
||||
return clk;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&clk_list_lock);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
@ -203,8 +219,8 @@ dump_clock(struct clk *parent, struct clkinf *r)
|
||||
|
||||
/* cost of this scan is small, but not linear... */
|
||||
r->nest = nest + NEST_DELTA;
|
||||
for (i = 3; i < at32_nr_clocks; i++) {
|
||||
clk = at32_clock_list[i];
|
||||
|
||||
list_for_each_entry(clk, &at32_clock_list, list) {
|
||||
if (clk->parent == parent)
|
||||
dump_clock(clk, r);
|
||||
}
|
||||
@ -215,6 +231,7 @@ static int clk_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct clkinf r;
|
||||
int i;
|
||||
struct clk *clk;
|
||||
|
||||
/* show all the power manager registers */
|
||||
seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL));
|
||||
@ -234,14 +251,25 @@ static int clk_show(struct seq_file *s, void *unused)
|
||||
|
||||
seq_printf(s, "\n");
|
||||
|
||||
/* show clock tree as derived from the three oscillators
|
||||
* we "know" are at the head of the list
|
||||
*/
|
||||
r.s = s;
|
||||
r.nest = 0;
|
||||
dump_clock(at32_clock_list[0], &r);
|
||||
dump_clock(at32_clock_list[1], &r);
|
||||
dump_clock(at32_clock_list[2], &r);
|
||||
/* protected from changes on the list while dumping */
|
||||
spin_lock(&clk_list_lock);
|
||||
|
||||
/* show clock tree as derived from the three oscillators */
|
||||
clk = clk_get(NULL, "osc32k");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
clk = clk_get(NULL, "osc0");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
clk = clk_get(NULL, "osc1");
|
||||
dump_clock(clk, &r);
|
||||
clk_put(clk);
|
||||
|
||||
spin_unlock(&clk_list_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,8 +12,13 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
|
||||
void at32_clk_register(struct clk *clk);
|
||||
|
||||
struct clk {
|
||||
struct list_head list; /* linking element */
|
||||
const char *name; /* Clock name/function */
|
||||
struct device *dev; /* Device the clock is used by */
|
||||
struct clk *parent; /* Parent clock, if any */
|
||||
@ -25,6 +30,3 @@ struct clk {
|
||||
u16 users; /* Enabled if non-zero */
|
||||
u16 index; /* Sibling index */
|
||||
};
|
||||
|
||||
extern struct clk *at32_clock_list[];
|
||||
extern unsigned int at32_nr_clocks;
|
||||
|
@ -83,4 +83,132 @@
|
||||
#define HMATRIX_BASE 0xfff00800
|
||||
#define SDRAMC_BASE 0xfff03800
|
||||
|
||||
/* LCDC on port C */
|
||||
#define ATMEL_LCDC_PC_CC (1ULL << 19)
|
||||
#define ATMEL_LCDC_PC_HSYNC (1ULL << 20)
|
||||
#define ATMEL_LCDC_PC_PCLK (1ULL << 21)
|
||||
#define ATMEL_LCDC_PC_VSYNC (1ULL << 22)
|
||||
#define ATMEL_LCDC_PC_DVAL (1ULL << 23)
|
||||
#define ATMEL_LCDC_PC_MODE (1ULL << 24)
|
||||
#define ATMEL_LCDC_PC_PWR (1ULL << 25)
|
||||
#define ATMEL_LCDC_PC_DATA0 (1ULL << 26)
|
||||
#define ATMEL_LCDC_PC_DATA1 (1ULL << 27)
|
||||
#define ATMEL_LCDC_PC_DATA2 (1ULL << 28)
|
||||
#define ATMEL_LCDC_PC_DATA3 (1ULL << 29)
|
||||
#define ATMEL_LCDC_PC_DATA4 (1ULL << 30)
|
||||
#define ATMEL_LCDC_PC_DATA5 (1ULL << 31)
|
||||
|
||||
/* LCDC on port D */
|
||||
#define ATMEL_LCDC_PD_DATA6 (1ULL << 0)
|
||||
#define ATMEL_LCDC_PD_DATA7 (1ULL << 1)
|
||||
#define ATMEL_LCDC_PD_DATA8 (1ULL << 2)
|
||||
#define ATMEL_LCDC_PD_DATA9 (1ULL << 3)
|
||||
#define ATMEL_LCDC_PD_DATA10 (1ULL << 4)
|
||||
#define ATMEL_LCDC_PD_DATA11 (1ULL << 5)
|
||||
#define ATMEL_LCDC_PD_DATA12 (1ULL << 6)
|
||||
#define ATMEL_LCDC_PD_DATA13 (1ULL << 7)
|
||||
#define ATMEL_LCDC_PD_DATA14 (1ULL << 8)
|
||||
#define ATMEL_LCDC_PD_DATA15 (1ULL << 9)
|
||||
#define ATMEL_LCDC_PD_DATA16 (1ULL << 10)
|
||||
#define ATMEL_LCDC_PD_DATA17 (1ULL << 11)
|
||||
#define ATMEL_LCDC_PD_DATA18 (1ULL << 12)
|
||||
#define ATMEL_LCDC_PD_DATA19 (1ULL << 13)
|
||||
#define ATMEL_LCDC_PD_DATA20 (1ULL << 14)
|
||||
#define ATMEL_LCDC_PD_DATA21 (1ULL << 15)
|
||||
#define ATMEL_LCDC_PD_DATA22 (1ULL << 16)
|
||||
#define ATMEL_LCDC_PD_DATA23 (1ULL << 17)
|
||||
|
||||
/* LCDC on port E */
|
||||
#define ATMEL_LCDC_PE_CC (1ULL << (32 + 0))
|
||||
#define ATMEL_LCDC_PE_DVAL (1ULL << (32 + 1))
|
||||
#define ATMEL_LCDC_PE_MODE (1ULL << (32 + 2))
|
||||
#define ATMEL_LCDC_PE_DATA0 (1ULL << (32 + 3))
|
||||
#define ATMEL_LCDC_PE_DATA1 (1ULL << (32 + 4))
|
||||
#define ATMEL_LCDC_PE_DATA2 (1ULL << (32 + 5))
|
||||
#define ATMEL_LCDC_PE_DATA3 (1ULL << (32 + 6))
|
||||
#define ATMEL_LCDC_PE_DATA4 (1ULL << (32 + 7))
|
||||
#define ATMEL_LCDC_PE_DATA8 (1ULL << (32 + 8))
|
||||
#define ATMEL_LCDC_PE_DATA9 (1ULL << (32 + 9))
|
||||
#define ATMEL_LCDC_PE_DATA10 (1ULL << (32 + 10))
|
||||
#define ATMEL_LCDC_PE_DATA11 (1ULL << (32 + 11))
|
||||
#define ATMEL_LCDC_PE_DATA12 (1ULL << (32 + 12))
|
||||
#define ATMEL_LCDC_PE_DATA16 (1ULL << (32 + 13))
|
||||
#define ATMEL_LCDC_PE_DATA17 (1ULL << (32 + 14))
|
||||
#define ATMEL_LCDC_PE_DATA18 (1ULL << (32 + 15))
|
||||
#define ATMEL_LCDC_PE_DATA19 (1ULL << (32 + 16))
|
||||
#define ATMEL_LCDC_PE_DATA20 (1ULL << (32 + 17))
|
||||
#define ATMEL_LCDC_PE_DATA21 (1ULL << (32 + 18))
|
||||
|
||||
|
||||
#define ATMEL_LCDC(PORT, PIN) (ATMEL_LCDC_##PORT##_##PIN)
|
||||
|
||||
|
||||
#define ATMEL_LCDC_PRI_24B_DATA ( \
|
||||
ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \
|
||||
ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \
|
||||
ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \
|
||||
ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
|
||||
ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \
|
||||
ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \
|
||||
ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \
|
||||
ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
|
||||
ATMEL_LCDC(PD, DATA16) | ATMEL_LCDC(PD, DATA17) | \
|
||||
ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \
|
||||
ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \
|
||||
ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
|
||||
|
||||
#define ATMEL_LCDC_ALT_24B_DATA ( \
|
||||
ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \
|
||||
ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \
|
||||
ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \
|
||||
ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
|
||||
ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \
|
||||
ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \
|
||||
ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \
|
||||
ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
|
||||
ATMEL_LCDC(PE, DATA16) | ATMEL_LCDC(PE, DATA17) | \
|
||||
ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \
|
||||
ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \
|
||||
ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
|
||||
|
||||
#define ATMEL_LCDC_PRI_15B_DATA ( \
|
||||
ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \
|
||||
ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \
|
||||
ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \
|
||||
ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \
|
||||
ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \
|
||||
ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) | \
|
||||
ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) | \
|
||||
ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
|
||||
|
||||
#define ATMEL_LCDC_ALT_15B_DATA ( \
|
||||
ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \
|
||||
ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \
|
||||
ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \
|
||||
ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \
|
||||
ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \
|
||||
ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) | \
|
||||
ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) | \
|
||||
ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
|
||||
|
||||
#define ATMEL_LCDC_PRI_CONTROL ( \
|
||||
ATMEL_LCDC(PC, CC) | ATMEL_LCDC(PC, DVAL) | \
|
||||
ATMEL_LCDC(PC, MODE) | ATMEL_LCDC(PC, PWR))
|
||||
|
||||
#define ATMEL_LCDC_ALT_CONTROL ( \
|
||||
ATMEL_LCDC(PE, CC) | ATMEL_LCDC(PE, DVAL) | \
|
||||
ATMEL_LCDC(PE, MODE) | ATMEL_LCDC(PC, PWR))
|
||||
|
||||
#define ATMEL_LCDC_CONTROL ( \
|
||||
ATMEL_LCDC(PC, HSYNC) | ATMEL_LCDC(PC, VSYNC) | \
|
||||
ATMEL_LCDC(PC, PCLK))
|
||||
|
||||
#define ATMEL_LCDC_PRI_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_24B_DATA)
|
||||
|
||||
#define ATMEL_LCDC_ALT_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
|
||||
|
||||
#define ATMEL_LCDC_PRI_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
|
||||
|
||||
#define ATMEL_LCDC_ALT_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
|
||||
|
||||
#endif /* __ASM_ARCH_AT32AP700X_H__ */
|
||||
|
@ -43,7 +43,7 @@ struct atmel_lcdfb_info;
|
||||
struct platform_device *
|
||||
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
unsigned long fbmem_start, unsigned long fbmem_len,
|
||||
unsigned int pin_config);
|
||||
u64 pin_mask);
|
||||
|
||||
struct usba_platform_data;
|
||||
struct platform_device *
|
||||
|
@ -1,8 +1,7 @@
|
||||
#ifndef __ASM_AVR32_ARCH_AT32AP_IO_H
|
||||
#define __ASM_AVR32_ARCH_AT32AP_IO_H
|
||||
|
||||
/* For "bizarre" halfword swapping */
|
||||
#include <linux/byteorder/swabb.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
#if defined(CONFIG_AP700X_32_BIT_SMC)
|
||||
# define __swizzle_addr_b(addr) (addr ^ 3UL)
|
||||
|
@ -21,9 +21,10 @@
|
||||
#define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */
|
||||
#define AT32_GPIOF_MULTIDRV 0x00000010 /* Enable multidriver option */
|
||||
|
||||
void at32_select_periph(unsigned int pin, unsigned int periph,
|
||||
unsigned long flags);
|
||||
void at32_select_periph(unsigned int port, unsigned int pin,
|
||||
unsigned int periph, unsigned long flags);
|
||||
void at32_select_gpio(unsigned int pin, unsigned long flags);
|
||||
void at32_deselect_pin(unsigned int pin);
|
||||
void at32_reserve_pin(unsigned int pin);
|
||||
|
||||
#endif /* __ASM_ARCH_PORTMUX_H__ */
|
||||
|
@ -35,7 +35,6 @@ static int __init pdc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static struct platform_driver pdc_driver = {
|
||||
.probe = pdc_probe,
|
||||
.driver = {
|
||||
.name = "pdc",
|
||||
},
|
||||
@ -43,6 +42,6 @@ static struct platform_driver pdc_driver = {
|
||||
|
||||
static int __init pdc_init(void)
|
||||
{
|
||||
return platform_driver_register(&pdc_driver);
|
||||
return platform_driver_probe(&pdc_driver, pdc_probe);
|
||||
}
|
||||
arch_initcall(pdc_init);
|
||||
|
@ -50,35 +50,48 @@ static struct pio_device *gpio_to_pio(unsigned int gpio)
|
||||
}
|
||||
|
||||
/* Pin multiplexing API */
|
||||
static DEFINE_SPINLOCK(pio_lock);
|
||||
|
||||
void __init at32_select_periph(unsigned int pin, unsigned int periph,
|
||||
unsigned long flags)
|
||||
void __init at32_select_periph(unsigned int port, u32 pin_mask,
|
||||
unsigned int periph, unsigned long flags)
|
||||
{
|
||||
struct pio_device *pio;
|
||||
unsigned int pin_index = pin & 0x1f;
|
||||
u32 mask = 1 << pin_index;
|
||||
|
||||
pio = gpio_to_pio(pin);
|
||||
/* assign and verify pio */
|
||||
pio = gpio_to_pio(port);
|
||||
if (unlikely(!pio)) {
|
||||
printk("pio: invalid pin %u\n", pin);
|
||||
printk(KERN_WARNING "pio: invalid port %u\n", port);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask)
|
||||
|| gpiochip_is_requested(&pio->chip, pin_index))) {
|
||||
printk("%s: pin %u is busy\n", pio->name, pin_index);
|
||||
/* Test if any of the requested pins is already muxed */
|
||||
spin_lock(&pio_lock);
|
||||
if (unlikely(pio->pinmux_mask & pin_mask)) {
|
||||
printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n",
|
||||
pio->name, pin_mask, pio->pinmux_mask & pin_mask);
|
||||
spin_unlock(&pio_lock);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pio_writel(pio, PUER, mask);
|
||||
pio->pinmux_mask |= pin_mask;
|
||||
|
||||
/* enable pull ups */
|
||||
pio_writel(pio, PUER, pin_mask);
|
||||
|
||||
/* select either peripheral A or B */
|
||||
if (periph)
|
||||
pio_writel(pio, BSR, mask);
|
||||
pio_writel(pio, BSR, pin_mask);
|
||||
else
|
||||
pio_writel(pio, ASR, mask);
|
||||
pio_writel(pio, ASR, pin_mask);
|
||||
|
||||
pio_writel(pio, PDR, mask);
|
||||
/* enable peripheral control */
|
||||
pio_writel(pio, PDR, pin_mask);
|
||||
|
||||
/* Disable pull ups if not requested. */
|
||||
if (!(flags & AT32_GPIOF_PULLUP))
|
||||
pio_writel(pio, PUDR, mask);
|
||||
pio_writel(pio, PUDR, pin_mask);
|
||||
|
||||
spin_unlock(&pio_lock);
|
||||
|
||||
return;
|
||||
|
||||
@ -134,6 +147,25 @@ fail:
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo a previous pin reservation. Will not affect the hardware
|
||||
* configuration.
|
||||
*/
|
||||
void at32_deselect_pin(unsigned int pin)
|
||||
{
|
||||
struct pio_device *pio;
|
||||
unsigned int pin_index = pin & 0x1f;
|
||||
|
||||
pio = gpio_to_pio(pin);
|
||||
if (unlikely(!pio)) {
|
||||
printk("pio: invalid pin %u\n", pin);
|
||||
dump_stack();
|
||||
return;
|
||||
}
|
||||
|
||||
clear_bit(pin_index, &pio->pinmux_mask);
|
||||
}
|
||||
|
||||
/* Reserve a pin, preventing anyone else from changing its configuration. */
|
||||
void __init at32_reserve_pin(unsigned int pin)
|
||||
{
|
||||
@ -382,7 +414,6 @@ static int __init pio_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static struct platform_driver pio_driver = {
|
||||
.probe = pio_probe,
|
||||
.driver = {
|
||||
.name = "pio",
|
||||
},
|
||||
@ -390,7 +421,7 @@ static struct platform_driver pio_driver = {
|
||||
|
||||
static int __init pio_init(void)
|
||||
{
|
||||
return platform_driver_register(&pio_driver);
|
||||
return platform_driver_probe(&pio_driver, pio_probe);
|
||||
}
|
||||
postcore_initcall(pio_init);
|
||||
|
||||
|
@ -5,4 +5,4 @@ oprofile-y := $(addprefix ../../../drivers/oprofile/, \
|
||||
event_buffer.o oprofile_files.o \
|
||||
oprofilefs.o oprofile_stats.o \
|
||||
timer_int.o)
|
||||
oprofile-y += op_model_avr32.o
|
||||
oprofile-y += op_model_avr32.o backtrace.o
|
||||
|
81
arch/avr32/oprofile/backtrace.c
Normal file
81
arch/avr32/oprofile/backtrace.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* AVR32 specific backtracing code for oprofile
|
||||
*
|
||||
* Copyright 2008 Weinmann GmbH
|
||||
*
|
||||
* Author: Nikolaus Voss <n.voss@weinmann.de>
|
||||
*
|
||||
* Based on i386 oprofile backtrace code by John Levon and David Smith
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/* The first two words of each frame on the stack look like this if we have
|
||||
* frame pointers */
|
||||
struct frame_head {
|
||||
unsigned long lr;
|
||||
struct frame_head *fp;
|
||||
};
|
||||
|
||||
/* copied from arch/avr32/kernel/process.c */
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
|
||||
{
|
||||
return (p > (unsigned long)tinfo)
|
||||
&& (p < (unsigned long)tinfo + THREAD_SIZE - 3);
|
||||
}
|
||||
|
||||
/* copied from arch/x86/oprofile/backtrace.c */
|
||||
static struct frame_head *dump_user_backtrace(struct frame_head *head)
|
||||
{
|
||||
struct frame_head bufhead[2];
|
||||
|
||||
/* Also check accessibility of one struct frame_head beyond */
|
||||
if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
|
||||
return NULL;
|
||||
if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
|
||||
return NULL;
|
||||
|
||||
oprofile_add_trace(bufhead[0].lr);
|
||||
|
||||
/* frame pointers should strictly progress back up the stack
|
||||
* (towards higher addresses) */
|
||||
if (bufhead[0].fp <= head)
|
||||
return NULL;
|
||||
|
||||
return bufhead[0].fp;
|
||||
}
|
||||
|
||||
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth)
|
||||
{
|
||||
/* Get first frame pointer */
|
||||
struct frame_head *head = (struct frame_head *)(regs->r7);
|
||||
|
||||
if (!user_mode(regs)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
/*
|
||||
* Traverse the kernel stack from frame to frame up to
|
||||
* "depth" steps.
|
||||
*/
|
||||
while (depth-- && valid_stack_ptr(task_thread_info(current),
|
||||
(unsigned long)head)) {
|
||||
oprofile_add_trace(head->lr);
|
||||
if (head->fp <= head)
|
||||
break;
|
||||
head = head->fp;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* Assume we have frame pointers in user mode process */
|
||||
while (depth-- && head)
|
||||
head = dump_user_backtrace(head);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#define AVR32_PERFCTR_IRQ_GROUP 0
|
||||
#define AVR32_PERFCTR_IRQ_LINE 1
|
||||
|
||||
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth);
|
||||
|
||||
enum { PCCNT, PCNT0, PCNT1, NR_counter };
|
||||
|
||||
struct avr32_perf_counter {
|
||||
@ -223,6 +225,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
|
||||
memcpy(ops, &avr32_perf_counter_ops,
|
||||
sizeof(struct oprofile_operations));
|
||||
|
||||
ops->backtrace = avr32_backtrace;
|
||||
|
||||
printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n");
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user