Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/ker…
Browse files Browse the repository at this point in the history
…nel/avr32

* 'for-linus' of git://www.atmel.no/~hskinnemoen/linux/kernel/avr32:
  [AVR32] Use per-controller spi_board_info structures
  [AVR32] Warn, don't BUG if clk_disable is called too many times
  [AVR32] Make sure all genclocks have a parent
  [AVR32] Remove unnecessary sys_nfsservctl conditional
  [AVR32] Wire up the SysV IPC calls properly
  [AVR32] Define ioremap_nocache, ioport_map and ioport_unmap
  [AVR32] Fix prototypes for __raw_writesb and friends
  • Loading branch information
Linus Torvalds committed Feb 16, 2007
2 parents f8abea8 + 41d8ca4 commit 8a03d9a
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 58 deletions.
9 changes: 3 additions & 6 deletions arch/avr32/boards/atstk1000/atstk1002.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -36,12 +35,11 @@ static struct eth_addr __initdata hw_addr[2];
static struct eth_platform_data __initdata eth_data[2];
extern struct lcdc_platform_data atstk1000_fb0_data;

static struct spi_board_info spi_board_info[] __initdata = {
static struct spi_board_info spi0_board_info[] __initdata = {
{
/* QVGA display */
.modalias = "ltv350qv",
.controller_data = (void *)GPIO_PIN_PA(4),
.max_speed_hz = 16000000,
.bus_num = 0,
.chip_select = 1,
},
};
Expand Down Expand Up @@ -149,8 +147,7 @@ static int __init atstk1002_init(void)

set_hw_addr(at32_add_device_eth(0, &eth_data[0]));

spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
at32_add_device_spi(0);
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
at32_add_device_lcdc(0, &atstk1000_fb0_data);

return 0;
Expand Down
22 changes: 13 additions & 9 deletions arch/avr32/kernel/syscall_table.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
* published by the Free Software Foundation.
*/

#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
#define sys_nfsservctl sys_ni_syscall
#endif

#if !defined(CONFIG_SYSV_IPC)
# define sys_ipc sys_ni_syscall
#endif

.section .rodata,"a",@progbits
.type sys_call_table,@object
.global sys_call_table
Expand Down Expand Up @@ -129,7 +121,7 @@ sys_call_table:
.long sys_getitimer /* 105 */
.long sys_swapoff
.long sys_sysinfo
.long sys_ipc
.long sys_ni_syscall /* was sys_ipc briefly */
.long sys_sendfile
.long sys_setdomainname /* 110 */
.long sys_newuname
Expand Down Expand Up @@ -287,4 +279,16 @@ sys_call_table:
.long sys_tee
.long sys_vmsplice
.long __sys_epoll_pwait /* 265 */
.long sys_msgget
.long sys_msgsnd
.long sys_msgrcv
.long sys_msgctl
.long sys_semget /* 270 */
.long sys_semop
.long sys_semctl
.long sys_semtimedop
.long sys_shmat
.long sys_shmget /* 275 */
.long sys_shmdt
.long sys_shmctl
.long sys_ni_syscall /* r8 is saturated at nr_syscalls */
144 changes: 111 additions & 33 deletions arch/avr32/mach-at32ap/at32ap7000.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/clk.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>

#include <asm/io.h>

Expand Down Expand Up @@ -310,8 +311,6 @@ static void genclk_mode(struct clk *clk, int enabled)
{
u32 control;

BUG_ON(clk->index > 7);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (enabled)
control |= SM_BIT(CEN);
Expand All @@ -325,11 +324,6 @@ static unsigned long genclk_get_rate(struct clk *clk)
u32 control;
unsigned long div = 1;

BUG_ON(clk->index > 7);

if (!clk->parent)
return 0;

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (control & SM_BIT(DIVEN))
div = 2 * (SM_BFEXT(DIV, control) + 1);
Expand All @@ -342,11 +336,6 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
u32 control;
unsigned long parent_rate, actual_rate, div;

BUG_ON(clk->index > 7);

if (!clk->parent)
return 0;

parent_rate = clk->parent->get_rate(clk->parent);
control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);

Expand All @@ -373,11 +362,8 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
{
u32 control;

BUG_ON(clk->index > 7);

printk("clk %s: new parent %s (was %s)\n",
clk->name, parent->name,
clk->parent ? clk->parent->name : "(null)");
clk->name, parent->name, clk->parent->name);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);

Expand All @@ -399,6 +385,22 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
return 0;
}

static void __init genclk_init_parent(struct clk *clk)
{
u32 control;
struct clk *parent;

BUG_ON(clk->index > 7);

control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
if (control & SM_BIT(OSCSEL))
parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1;
else
parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0;

clk->parent = parent;
}

/* --------------------------------------------------------------------
* System peripherals
* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -750,8 +752,41 @@ static struct resource atmel_spi1_resource[] = {
DEFINE_DEV(atmel_spi, 1);
DEV_CLK(spi_clk, atmel_spi1, pba, 1);

struct platform_device *__init at32_add_device_spi(unsigned int id)
static void
at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
unsigned int n, const u8 *pins)
{
unsigned int pin, mode;

for (; n; n--, b++) {
b->bus_num = bus_num;
if (b->chip_select >= 4)
continue;
pin = (unsigned)b->controller_data;
if (!pin) {
pin = pins[b->chip_select];
b->controller_data = (void *)pin;
}
mode = AT32_GPIOF_OUTPUT;
if (!(b->mode & SPI_CS_HIGH))
mode |= AT32_GPIOF_HIGH;
at32_select_gpio(pin, mode);
}
}

struct platform_device *__init
at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
{
/*
* Manage the chipselects as GPIOs, normally using the same pins
* the SPI controller expects; but boards can use other pins.
*/
static u8 __initdata spi0_pins[] =
{ GPIO_PIN_PA(3), GPIO_PIN_PA(4),
GPIO_PIN_PA(5), GPIO_PIN_PA(20), };
static u8 __initdata spi1_pins[] =
{ GPIO_PIN_PB(2), GPIO_PIN_PB(3),
GPIO_PIN_PB(4), GPIO_PIN_PA(27), };
struct platform_device *pdev;

switch (id) {
Expand All @@ -760,35 +795,22 @@ struct platform_device *__init at32_add_device_spi(unsigned int id)
select_peripheral(PA(0), PERIPH_A, 0); /* MISO */
select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */
select_peripheral(PA(2), PERIPH_A, 0); /* SCK */

/* NPCS[2:0] */
at32_select_gpio(GPIO_PIN_PA(3),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PA(4),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PA(5),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_spi_setup_slaves(0, b, n, spi0_pins);
break;

case 1:
pdev = &atmel_spi1_device;
select_peripheral(PB(0), PERIPH_B, 0); /* MISO */
select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */
select_peripheral(PB(5), PERIPH_B, 0); /* SCK */

/* NPCS[2:0] */
at32_select_gpio(GPIO_PIN_PB(2),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PB(3),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_select_gpio(GPIO_PIN_PB(4),
AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
at32_spi_setup_slaves(1, b, n, spi1_pins);
break;

default:
return NULL;
}

spi_register_board_info(b, n);
platform_device_register(pdev);
return pdev;
}
Expand Down Expand Up @@ -872,6 +894,50 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
return pdev;
}

/* --------------------------------------------------------------------
* GCLK
* -------------------------------------------------------------------- */
static struct clk gclk0 = {
.name = "gclk0",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 0,
};
static struct clk gclk1 = {
.name = "gclk1",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 1,
};
static struct clk gclk2 = {
.name = "gclk2",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 2,
};
static struct clk gclk3 = {
.name = "gclk3",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 3,
};
static struct clk gclk4 = {
.name = "gclk4",
.mode = genclk_mode,
.get_rate = genclk_get_rate,
.set_rate = genclk_set_rate,
.set_parent = genclk_set_parent,
.index = 4,
};

struct clk *at32_clock_list[] = {
&osc32k,
&osc0,
Expand Down Expand Up @@ -908,6 +974,11 @@ struct clk *at32_clock_list[] = {
&atmel_spi1_spi_clk,
&lcdc0_hclk,
&lcdc0_pixclk,
&gclk0,
&gclk1,
&gclk2,
&gclk3,
&gclk4,
};
unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);

Expand Down Expand Up @@ -936,6 +1007,13 @@ void __init at32_clock_init(void)
if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
pll1.parent = &osc1;

genclk_init_parent(&gclk0);
genclk_init_parent(&gclk1);
genclk_init_parent(&gclk2);
genclk_init_parent(&gclk3);
genclk_init_parent(&gclk4);
genclk_init_parent(&lcdc0_pixclk);

/*
* Turn on all clocks that have at least one user already, and
* turn off everything else. We only do this for module
Expand Down
6 changes: 5 additions & 1 deletion arch/avr32/mach-at32ap/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ EXPORT_SYMBOL(clk_enable);

static void __clk_disable(struct clk *clk)
{
BUG_ON(clk->users == 0);
if (clk->users == 0) {
printk(KERN_ERR "%s: mismatched disable\n", clk->name);
WARN_ON(1);
return;
}

if (--clk->users == 0 && clk->mode)
clk->mode(clk, 0);
Expand Down
4 changes: 3 additions & 1 deletion include/asm-avr32/arch-at32ap/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ struct eth_platform_data {
struct platform_device *
at32_add_device_eth(unsigned int id, struct eth_platform_data *data);

struct platform_device *at32_add_device_spi(unsigned int id);
struct spi_board_info;
struct platform_device *
at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n);

struct lcdc_platform_data {
unsigned long fbmem_start;
Expand Down
23 changes: 17 additions & 6 deletions include/asm-avr32/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ static __inline__ void * phys_to_virt(unsigned long address)
* Generic IO read/write. These perform native-endian accesses. Note
* that some architectures will want to re-define __raw_{read,write}w.
*/
extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen);
extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
extern void __raw_writesl(void __iomem *addr, const void *data, int longlen);

extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
extern void __raw_readsl(unsigned int addr, void *data, int longlen);
extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);

static inline void writeb(unsigned char b, volatile void __iomem *addr)
{
Expand Down Expand Up @@ -252,6 +252,9 @@ extern void __iounmap(void __iomem *addr);
#define ioremap(offset, size) \
__ioremap((offset), (size), 0)

#define ioremap_nocache(offset, size) \
__ioremap((offset), (size), 0)

#define iounmap(addr) \
__iounmap(addr)

Expand All @@ -263,6 +266,14 @@ extern void __iounmap(void __iomem *addr);
#define page_to_bus page_to_phys
#define bus_to_page phys_to_page

/*
* Create a virtual mapping cookie for an IO port range. There exists
* no such thing as port-based I/O on AVR32, so a regular ioremap()
* should do what we need.
*/
#define ioport_map(port, nr) ioremap(port, nr)
#define ioport_unmap(port) iounmap(port)

#define dma_cache_wback_inv(_start, _size) \
flush_dcache_region(_start, _size)
#define dma_cache_inv(_start, _size) \
Expand Down
Loading

0 comments on commit 8a03d9a

Please sign in to comment.