Skip to content

Commit

Permalink
[ARM] 3098/1: pxa2xx disable ssp irq
Browse files Browse the repository at this point in the history
Patch from Liam Girdwood

This patch allows users of the pxa SSP driver to register their own irq
handlers instead of using the default SSP handler. It also cleans up the
CKEN clock and irq detection as the values are now stored in a table.

This patch replaces 2845/1

Changes:-
o Added flags parameter to ssp_init()
o Added SSP_NO_IRQ flag to disable registering of ssp irq handler (for
drivers that want to register their own handler)
o Cleaned up clock and irq detection, values are now stored in table.
o Added build changes to allow other drivers (e.g audio) to select the
ssp driver.
o corgi_ssp.c changed to use new interface.

Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Liam Girdwood authored and Russell King committed Nov 10, 2005
1 parent 078abcf commit b216c01
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 92 deletions.
7 changes: 7 additions & 0 deletions arch/arm/mach-pxa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
depends PXA_SHARPSL_25x
select PXA_SHARP_C7xx
select PXA_SSP

config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
Expand Down Expand Up @@ -102,12 +103,18 @@ config IWMMXT

config PXA_SHARP_C7xx
bool
select PXA_SSP
help
Enable support for all Sharp C7xx models

config PXA_SHARP_Cxx00
bool
select PXA_SSP
help
Enable common support for Sharp Cxx00 models

config PXA_SSP
tristate
help
Enable support for PXA2xx SSP ports
endif
5 changes: 3 additions & 2 deletions arch/arm/mach-pxa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
obj-$(CONFIG_MACH_TOSA) += tosa.o

Expand All @@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y)

# Misc features
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_PXA_SSP) += ssp.o

ifeq ($(CONFIG_PXA27x),y)
obj-$(CONFIG_PM) += standby.o
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-pxa/corgi_ssp.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct device *dev)
GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/

ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);

if (ret)
printk(KERN_ERR "Unable to register SSP handler!\n");
Expand Down
128 changes: 40 additions & 88 deletions arch/arm/mach-pxa/ssp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* 22nd Aug 2003 Initial version.
* 20th Dec 2004 Added ssp_config for changing port config without
* closing the port.
* 4th Aug 2005 Added option to disable irq handler registration and
* cleaned up irq and clock detection.
*/

#include <linux/module.h>
Expand All @@ -37,6 +39,26 @@

#define PXA_SSP_PORTS 3

struct ssp_info_ {
int irq;
u32 clock;
};

/*
* SSP port clock and IRQ settings
*/
static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
#if defined (CONFIG_PXA27x)
{IRQ_SSP, CKEN23_SSP1},
{IRQ_SSP2, CKEN3_SSP2},
{IRQ_SSP3, CKEN4_SSP3},
#else
{IRQ_SSP, CKEN3_SSP},
{IRQ_NSSP, CKEN9_NSSP},
{IRQ_ASSP, CKEN10_ASSP},
#endif
};

static DECLARE_MUTEX(sem);
static int use_count[PXA_SSP_PORTS] = {0, 0, 0};

Expand Down Expand Up @@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
* %-EBUSY if the resources are already in use
* %0 on success
*/
int ssp_init(struct ssp_dev *dev, u32 port)
int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
{
int ret, irq;
int ret;

if (port > PXA_SSP_PORTS || port == 0)
return -ENODEV;
Expand All @@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port)
up(&sem);
return -EBUSY;
}

switch (port) {
case 1:
irq = IRQ_SSP;
break;
#if defined (CONFIG_PXA27x)
case 2:
irq = IRQ_SSP2;
break;
case 3:
irq = IRQ_SSP3;
break;
#else
case 2:
irq = IRQ_NSSP;
break;
case 3:
irq = IRQ_ASSP;
break;
#endif
default:
return -ENODEV;
}

dev->port = port;

ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
if (ret)
goto out_region;
/* do we need to get irq */
if (!(init_flags & SSP_NO_IRQ)) {
ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
0, "SSP", dev);
if (ret)
goto out_region;
dev->irq = ssp_info[port-1].irq;
} else
dev->irq = 0;

/* turn on SSP port clock */
switch (dev->port) {
#if defined (CONFIG_PXA27x)
case 1:
pxa_set_cken(CKEN23_SSP1, 1);
break;
case 2:
pxa_set_cken(CKEN3_SSP2, 1);
break;
case 3:
pxa_set_cken(CKEN4_SSP3, 1);
break;
#else
case 1:
pxa_set_cken(CKEN3_SSP, 1);
break;
case 2:
pxa_set_cken(CKEN9_NSSP, 1);
break;
case 3:
pxa_set_cken(CKEN10_ASSP, 1);
break;
#endif
}

pxa_set_cken(ssp_info[port-1].clock, 1);
up(&sem);
return 0;

Expand All @@ -301,46 +282,17 @@ int ssp_init(struct ssp_dev *dev, u32 port)
*/
void ssp_exit(struct ssp_dev *dev)
{
int irq;

down(&sem);
SSCR0_P(dev->port) &= ~SSCR0_SSE;

/* find irq, save power and turn off SSP port clock */
switch (dev->port) {
#if defined (CONFIG_PXA27x)
case 1:
irq = IRQ_SSP;
pxa_set_cken(CKEN23_SSP1, 0);
break;
case 2:
irq = IRQ_SSP2;
pxa_set_cken(CKEN3_SSP2, 0);
break;
case 3:
irq = IRQ_SSP3;
pxa_set_cken(CKEN4_SSP3, 0);
break;
#else
case 1:
irq = IRQ_SSP;
pxa_set_cken(CKEN3_SSP, 0);
break;
case 2:
irq = IRQ_NSSP;
pxa_set_cken(CKEN9_NSSP, 0);
break;
case 3:
irq = IRQ_ASSP;
pxa_set_cken(CKEN10_ASSP, 0);
break;
#endif
default:
printk(KERN_WARNING "SSP: tried to close invalid port\n");
return;
if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
printk(KERN_WARNING "SSP: tried to close invalid port\n");
return;
}

free_irq(irq, dev);
pxa_set_cken(ssp_info[dev->port-1].clock, 0);
if (dev->irq)
free_irq(dev->irq, dev);
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
use_count[dev->port - 1]--;
up(&sem);
Expand Down
8 changes: 7 additions & 1 deletion include/asm-arm/arch-pxa/ssp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#ifndef SSP_H
#define SSP_H

/*
* SSP initialisation flags
*/
#define SSP_NO_IRQ 0x1 /* don't register an irq handler in SSP driver */

struct ssp_state {
u32 cr0;
u32 cr1;
Expand All @@ -31,6 +36,7 @@ struct ssp_dev {
u32 flags;
u32 psp_flags;
u32 speed;
int irq;
};

int ssp_write_word(struct ssp_dev *dev, u32 data);
Expand All @@ -40,7 +46,7 @@ void ssp_enable(struct ssp_dev *dev);
void ssp_disable(struct ssp_dev *dev);
void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
int ssp_init(struct ssp_dev *dev, u32 port);
int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
void ssp_exit(struct ssp_dev *dev);

Expand Down

0 comments on commit b216c01

Please sign in to comment.