Skip to content

Commit

Permalink
[ARM] ohci-pxa27x: introduce flags to avoid direct access to OHCI reg…
Browse files Browse the repository at this point in the history
…isters

Direct access to USB host controller registers is considered to be not
portable, and is usually a bad sign for poorly abstracted interface.
Introduce .flags and .power_on_delay to "struct pxaohci_platform_data"
so that most platforms don't bother to write their own .init/.exit()
sequences.

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Eric Miao authored and Russell King committed Oct 7, 2008
1 parent 52358ba commit 097b533
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 104 deletions.
11 changes: 1 addition & 10 deletions arch/arm/mach-pxa/cm-x270.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,18 +257,9 @@ static inline void cmx270_init_2700G(void) {}

/* PXA27x OHCI controller setup */
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int cmx270_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low */
UHCHR = (UHCHR | UHCHR_PCPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data cmx270_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = cmx270_ohci_init,
.flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
};

static void __init cmx270_init_ohci(void)
Expand Down
12 changes: 2 additions & 10 deletions arch/arm/mach-pxa/cm-x300.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,19 +365,11 @@ static inline void cm_x300_init_mmc(void) {}
#endif

#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int cm_x300_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low */
UHCHR = (UHCHR | UHCHR_PCPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = cm_x300_ohci_init,
.flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
};

static void __init cm_x300_init_ohci(void)
{
pxa_set_ohci_info(&cm_x300_ohci_platform_data);
Expand Down
5 changes: 1 addition & 4 deletions arch/arm/mach-pxa/em-x270.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,6 @@ static inline void em_x270_init_nand(void) {}
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int em_x270_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low */
UHCHR = (UHCHR | UHCHR_PCPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);

/* enable port 2 transiever */
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;

Expand All @@ -385,6 +381,7 @@ static int em_x270_ohci_init(struct device *dev)

static struct pxaohci_platform_data em_x270_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
.init = em_x270_ohci_init,
};

Expand Down
16 changes: 16 additions & 0 deletions arch/arm/mach-pxa/include/mach/ohci.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ struct pxaohci_platform_data {
int (*init)(struct device *);
void (*exit)(struct device *);

unsigned long flags;
#define ENABLE_PORT1 (1 << 0)
#define ENABLE_PORT2 (1 << 1)
#define ENABLE_PORT3 (1 << 2)
#define ENABLE_PORT_ALL (ENABLE_PORT1 | ENABLE_PORT2 | ENABLE_PORT3)

#define POWER_SENSE_LOW (1 << 3)
#define POWER_CONTROL_LOW (1 << 4)
#define NO_OC_PROTECTION (1 << 5)
#define OC_MODE_GLOBAL (0 << 6)
#define OC_MODE_PERPORT (1 << 6)

int power_on_delay; /* Power On to Power Good time - in ms
* HCD must wait for this duration before
* accessing a powered on port
*/
int port_mode;
#define PMM_NPS_MODE 1
#define PMM_GLOBAL_MODE 2
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mach-pxa/include/mach/pxa-regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@

#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */
#define UHCRHDA_NOCP (1 << 12) /* No over current protection */
#define UHCRHDA_OCPM (1 << 11) /* Over Current Protection Mode */
#define UHCRHDA_POTPGT(x) \
(((x) & 0xff) << 24) /* Power On To Power Good Time */

#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */
#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */
Expand Down
12 changes: 1 addition & 11 deletions arch/arm/mach-pxa/lpd270.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,19 +448,9 @@ static struct platform_device *platform_devices[] __initdata = {
&lpd270_flash_device[1],
};

static int lpd270_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data lpd270_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = lpd270_ohci_init,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
};

static void __init lpd270_init(void)
Expand Down
14 changes: 3 additions & 11 deletions arch/arm/mach-pxa/magician.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,18 +669,10 @@ static struct pxamci_platform_data magician_mci_info = {
* USB OHCI
*/

static int magician_ohci_init(struct device *dev)
{
UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data magician_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
.init = magician_ohci_init,
.power_budget = 0,
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
.power_budget = 0,
};


Expand Down
12 changes: 1 addition & 11 deletions arch/arm/mach-pxa/mainstone.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,19 +508,9 @@ static struct platform_device *platform_devices[] __initdata = {
&mst_gpio_keys_device,
};

static int mainstone_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data mainstone_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = mainstone_ohci_init,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
};

#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
Expand Down
30 changes: 2 additions & 28 deletions arch/arm/mach-pxa/pcm990-baseboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,36 +328,10 @@ static struct pxamci_platform_data pcm990_mci_platform_data = {
.exit = pcm990_mci_exit,
};

/*
* init OHCI hardware to work with
*
* Note: Only USB port 1 (host only) is connected
*
* GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
* GPIO89 (USBHPEN#1): power-on out, on when low
*/
static int pcm990_ohci_init(struct device *dev)
{
/*
* disable USB port 2 and 3
* power sense is active low
*/
UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
/*
* wait 10ms after Power on
* overcurrent per port
* power switch per port
*/
UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */

return 0;
}

static struct pxaohci_platform_data pcm990_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = pcm990_ohci_init,
.exit = NULL,
.flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
.power_on_delay = 10,
};

/*
Expand Down
10 changes: 2 additions & 8 deletions arch/arm/mach-pxa/spitz.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,19 +495,13 @@ static int spitz_ohci_init(struct device *dev)
*/
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;

gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);

UHCHR = (UHCHR) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);

UHCRHDA |= UHCRHDA_NOCP;

return 0;
return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
}

static struct pxaohci_platform_data spitz_ohci_platform_data = {
.port_mode = PMM_NPS_MODE,
.init = spitz_ohci_init,
.flags = ENABLE_PORT_ALL | NO_OC_PROTECTION,
.power_budget = 150,
};

Expand Down
12 changes: 1 addition & 11 deletions arch/arm/mach-pxa/trizeps4.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,19 +425,9 @@ static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
/****************************************************************************
* OHCI USB port
****************************************************************************/
static int trizeps4_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);

return 0;
}

static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = trizeps4_ohci_init,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
};

static struct map_desc trizeps4_io_desc[] __initdata = {
Expand Down
37 changes: 37 additions & 0 deletions drivers/usb/host/ohci-pxa27x.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,41 @@ extern int usb_disabled(void);

/*-------------------------------------------------------------------------*/

static inline void pxa27x_setup_hc(struct pxaohci_platform_data *inf)
{
uint32_t uhchr = UHCHR;
uint32_t uhcrhda = UHCRHDA;

if (inf->flags & ENABLE_PORT1)
uhchr &= ~UHCHR_SSEP1;

if (inf->flags & ENABLE_PORT2)
uhchr &= ~UHCHR_SSEP2;

if (inf->flags & ENABLE_PORT3)
uhchr &= ~UHCHR_SSEP3;

if (inf->flags & POWER_CONTROL_LOW)
uhchr |= UHCHR_PCPL;

if (inf->flags & POWER_SENSE_LOW)
uhchr |= UHCHR_PSPL;

if (inf->flags & NO_OC_PROTECTION)
uhcrhda |= UHCRHDA_NOCP;

if (inf->flags & OC_MODE_PERPORT)
uhcrhda |= UHCRHDA_OCPM;

if (inf->power_on_delay) {
uhcrhda &= ~UHCRHDA_POTPGT(0xff);
uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
}

UHCHR = uhchr;
UHCRHDA = uhcrhda;
}

static int pxa27x_start_hc(struct device *dev)
{
int retval = 0;
Expand All @@ -93,6 +128,8 @@ static int pxa27x_start_hc(struct device *dev)
while (UHCHR & UHCHR_FSBIR)
cpu_relax();

pxa27x_setup_hc(inf);

if (inf->init)
retval = inf->init(dev);

Expand Down

0 comments on commit 097b533

Please sign in to comment.