[ARM] ohci-pxa27x: introduce flags to avoid direct access to OHCI registers
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>
This commit is contained in:
parent
52358ba3a8
commit
097b53348f
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user