Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 435d444a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/home/rmk/linux-2.6-arm

parents 22d0def9 484ae6bd
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
			S3C24XX USB Host support
			========================



Introduction
------------

  This document details the S3C2410/S3C2440 in-built OHCI USB host support.

Configuration
-------------

  Enable at least the following kernel options:

  menuconfig:

   Device Drivers  --->
     USB support  --->
       <*> Support for Host-side USB
       <*>   OHCI HCD support


  .config:
    CONFIG_USB
    CONFIG_USB_OHCI_HCD


  Once these options are configured, the standard set of USB device
  drivers can be configured and used.


Board Support
-------------

  The driver attaches to a platform device, which will need to be
  added by the board specific support file in linux/arch/arm/mach-s3c2410,
  such as mach-bast.c or mach-smdk2410.c

  The platform device's platform_data field is only needed if the
  board implements extra power control or over-current monitoring.

  The OHCI driver does not ensure the state of the S3C2410's MISCCTRL
  register, so if both ports are to be used for the host, then it is
  the board support file's responsibility to ensure that the second
  port is configured to be connected to the OHCI core.


Platform Data
-------------

  See linux/include/asm-arm/arch-s3c2410/usb-control.h for the
  descriptions of the platform device data. An implementation
  can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .

  The `struct s3c2410_hcd_info` contains a pair of functions
  that get called to enable over-current detection, and to
  control the port power status.

  The ports are numbered 0 and 1.

  power_control:

    Called to enable or disable the power on the port.

  enable_oc:

    Called to enable or disable the over-current monitoring.
    This should claim or release the resources being used to
    check the power condition on the port, such as an IRQ.

  report_oc:

    The OHCI driver fills this field in for the over-current code
    to call when there is a change to the over-current state on
    an port. The ports argument is a bitmask of 1 bit per port,
    with bit X being 1 for an over-current on port X.

    The function s3c2410_usb_report_oc() has been provided to
    ensure this is called correctly.

  port[x]:

    This is struct describes each port, 0 or 1. The platform driver
    should set the flags field of each port to S3C_HCDFLG_USED if
    the port is enabled.



Document Author
---------------

Ben Dooks, (c) 2005 Simtec Electronics
+13 −5
Original line number Diff line number Diff line
/* linux/arch/arm/mach-s3c2410/usb-simtec.c
 *
 * Copyright (c) 2004 Simtec Electronics
 * Copyright (c) 2004,2005 Simtec Electronics
 *   Ben Dooks <ben@simtec.co.uk>
 *
 * http://www.simtec.co.uk/products/EB2410ITX/
@@ -14,6 +14,8 @@
 * Modifications:
 *	14-Sep-2004 BJD  Created
 *	18-Oct-2004 BJD  Cleanups, and added code to report OC cleared
 *	09-Aug-2005 BJD  Renamed s3c2410_report_oc to s3c2410_usb_report_oc
 *	09-Aug-2005 BJD  Ports powered only if both are enabled
*/

#define DEBUG
@@ -47,13 +49,19 @@
 * designed boards.
*/

static unsigned int power_state[2];

static void
usb_simtec_powercontrol(int port, int to)
{
	pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);

	if (port == 1)
		s3c2410_gpio_setpin(S3C2410_GPB4, to ? 0:1);
	power_state[port] = to;

	if (power_state[0] && power_state[1])
		s3c2410_gpio_setpin(S3C2410_GPB4, 0);
	else
		s3c2410_gpio_setpin(S3C2410_GPB4, 1);
}

static irqreturn_t
@@ -63,10 +71,10 @@ usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs)

	if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
		pr_debug("usb_simtec: over-current irq (oc detected)\n");
		s3c2410_report_oc(info, 3);
		s3c2410_usb_report_oc(info, 3);
	} else {
		pr_debug("usb_simtec: over-current irq (oc cleared)\n");
		s3c2410_report_oc(info, 0);
		s3c2410_usb_report_oc(info, 0);
	}

	return IRQ_HANDLED;
+14 −3
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ static void __init build_mem_type_table(void)
{
	struct cachepolicy *cp;
	unsigned int cr = get_cr();
	unsigned int user_pgprot;
	int cpu_arch = cpu_architecture();
	int i;

@@ -408,6 +409,9 @@ static void __init build_mem_type_table(void)
		}
	}

	cp = &cache_policies[cachepolicy];
	user_pgprot = cp->pte;

	/*
	 * ARMv6 and above have extended page tables.
	 */
@@ -426,11 +430,18 @@ static void __init build_mem_type_table(void)
		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;

		/*
		 * Mark the device area as "shared device"
		 */
		mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
		mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
	}

	cp = &cache_policies[cachepolicy];
		/*
		 * User pages need to be mapped with the ASID
		 * (iow, non-global)
		 */
		user_pgprot |= L_PTE_ASID;
	}

	if (cpu_arch >= CPU_ARCH_ARMv5) {
		mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
@@ -448,7 +459,7 @@ static void __init build_mem_type_table(void)

	for (i = 0; i < 16; i++) {
		unsigned long v = pgprot_val(protection_map[i]);
		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte;
		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
		protection_map[i] = __pgprot(v);
	}

+8 −14
Original line number Diff line number Diff line
@@ -111,12 +111,6 @@ ENTRY(cpu_v6_switch_mm)
	mcr	p15, 0, r1, c13, c0, 1		@ set context ID
	mov	pc, lr

#define nG	(1 << 11)
#define APX	(1 << 9)
#define AP1	(1 << 5)
#define AP0	(1 << 4)
#define XN	(1 << 0)

/*
 *	cpu_v6_set_pte(ptep, pte)
 *
@@ -139,24 +133,24 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte)
	str	r1, [r0], #-2048		@ linux version

	bic	r2, r1, #0x00000ff0
	bic	r2, r1, #0x000007f0
	bic	r2, r2, #0x00000003
	orr	r2, r2, #AP0 | 2
	orr	r2, r2, #PTE_EXT_AP0 | 2

	tst	r1, #L_PTE_WRITE
	tstne	r1, #L_PTE_DIRTY
	orreq	r2, r2, #APX
	orreq	r2, r2, #PTE_EXT_APX

	tst	r1, #L_PTE_USER
	orrne	r2, r2, #AP1 | nG
	tstne	r2, #APX
	bicne	r2, r2, #APX | AP0
	orrne	r2, r2, #PTE_EXT_AP1
	tstne	r2, #PTE_EXT_APX
	bicne	r2, r2, #PTE_EXT_APX | PTE_EXT_AP0

	tst	r1, #L_PTE_YOUNG
	biceq	r2, r2, #APX | AP1 | AP0
	biceq	r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK

@	tst	r1, #L_PTE_EXEC
@	orreq	r2, r2, #XN
@	orreq	r2, r2, #PTE_EXT_XN

	tst	r1, #L_PTE_PRESENT
	moveq	r2, #0
+6 −2
Original line number Diff line number Diff line
@@ -717,6 +717,9 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
	DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
	DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);

	/* enable LCD controller clock */
	pxa_set_cken(CKEN16_LCD, 1);

	/* Sequence from 11.7.10 */
	LCCR3 = fbi->reg_lccr3;
	LCCR2 = fbi->reg_lccr2;
@@ -750,6 +753,9 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)

	schedule_timeout(20 * HZ / 1000);
	remove_wait_queue(&fbi->ctrlr_wait, &wait);

	/* disable LCD controller clock */
	pxa_set_cken(CKEN16_LCD, 0);
}

/*
@@ -1299,8 +1305,6 @@ int __init pxafb_probe(struct device *dev)
		ret = -ENOMEM;
		goto failed;
	}
	/* enable LCD controller clock */
	pxa_set_cken(CKEN16_LCD, 1);

	ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
	if (ret) {
Loading