git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Digging through old vendor code
@ 2008-01-13  4:09 Jon Smirl
  2008-01-13  4:41 ` Linus Torvalds
  0 siblings, 1 reply; 7+ messages in thread
From: Jon Smirl @ 2008-01-13  4:09 UTC (permalink / raw)
  To: Git Mailing List

I have a file that a vendor has modified. It's a serial driver so I
know which directory the original file came from. Is there a way to
ask git to search through all of the past versions of all of the files
in this directory and give me the top two or three choices as to what
file the vendor originally copied before staring to edit? This is the
same problem as picking the best diff base.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
  2008-01-13  4:09 Digging through old vendor code Jon Smirl
@ 2008-01-13  4:41 ` Linus Torvalds
  0 siblings, 0 replies; 7+ messages in thread
From: Linus Torvalds @ 2008-01-13  4:41 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Git Mailing List



On Sat, 12 Jan 2008, Jon Smirl wrote:
>
> I have a file that a vendor has modified. It's a serial driver so I
> know which directory the original file came from. Is there a way to
> ask git to search through all of the past versions of all of the files
> in this directory and give me the top two or three choices as to what
> file the vendor originally copied before staring to edit? This is the
> same problem as picking the best diff base.

Heh. Maybe you could just use the rename logic?

Example of what *might* work:

 - go to the directory in the git tree you think the file came from

 - delete all the files that are *potential* sources (eg "rm *.c")

 - add the new file to that directory

 - commit the end result

 - ask git to find the best rename possibility, using a low rename 
   detection score, something like:

	git show -M1%

(and no, I don't guarantee that that "-M1%" is the right syntax, and in 
general you might well want to play with this concept a bit..)

No guarantees, but it just might work..

		Linus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
@ 2008-01-13 16:28 linux
  2008-01-13 17:04 ` Jon Smirl
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: linux @ 2008-01-13 16:28 UTC (permalink / raw)
  To: git, jonsmirl, torvalds; +Cc: linux

> Heh. Maybe you could just use the rename logic?
>
> [How-to snipped]

Clever idea, but I think the real problem was to figure out what VERSION
of the file was the base; i.e. to look through history.

Still, it should be possible to adapt the technique...

#!/bin/sh

# List of files we are looking to copy from
SRC="drivers/serial/"
# Temporary work directory
DST=/tmp/work
git-clone -l -n -s . $DST
{ cd $DST; git-symbolic-ref HEAD refs/heads/DELETEME; }
for i in `git-rev-list v2.6.20..v2.6.24-rc6 -- $SRC`; do
        j=`git-describe $i`
        git-archive --prefix="$j/" $i -- $SRC | tar xf - -C $DST
        # This is abusing the index, but it saves space...
        { cd $DST; git add $j; rm -rf $j; }
done

# And  now proceed as per Linus's idea...
# Except we have it all in the index; no need
# to actually make a commit...

cd $DST
cp $target_file $DST
{ cd $DST; git-diff-files -M...; }


Maybe a real git wizard will show me how to insert the index entries
directly without ever doing anything as pedestrian as extracting, hashing,
and then deleting the files, but it's still not that bad.

And it's kind of a neat example of using the index as a staging area
for a commit.

(Exercise for the reader: the above gets a complete copy of every file in
the directory for every commit in qhich ANY file in the directory changed.
Better would be to do the git-rev-list per-file, so you only add unique
file versions.  This requires an outer loop over file names and a more
careful pathname specification to git add in the inner loop.)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
  2008-01-13 16:28 linux
@ 2008-01-13 17:04 ` Jon Smirl
  2008-01-13 17:31 ` Jon Smirl
  2008-01-14 12:08 ` Jeff King
  2 siblings, 0 replies; 7+ messages in thread
From: Jon Smirl @ 2008-01-13 17:04 UTC (permalink / raw)
  To: linux@horizon.com; +Cc: git, torvalds

The vendor gave me an edited file with support for their device. The
original was copied from the kernel somewhere around 2.6.15 and then
edited. Nobody remembers what the source file was but there are a
couple of fairly close matches.

Diffing against the current kernel mixes the two sets of changes -
what the vendor did and what changed in the core kernel. I'm sorting
this out by hand but it is 3,000 lines of diffs.

It is an interesting problem to use the git history to try and
discover the original source file.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
  2008-01-13 16:28 linux
  2008-01-13 17:04 ` Jon Smirl
@ 2008-01-13 17:31 ` Jon Smirl
  2008-01-14 12:08 ` Jeff King
  2 siblings, 0 replies; 7+ messages in thread
From: Jon Smirl @ 2008-01-13 17:31 UTC (permalink / raw)
  To: linux@horizon.com; +Cc: git, torvalds

[-- Attachment #1: Type: text/plain, Size: 2020 bytes --]

On 13 Jan 2008 11:28:06 -0500, linux@horizon.com <linux@horizon.com> wrote:
> > Heh. Maybe you could just use the rename logic?
> >
> > [How-to snipped]
>
> Clever idea, but I think the real problem was to figure out what VERSION
> of the file was the base; i.e. to look through history.
>
> Still, it should be possible to adapt the technique...
>
> #!/bin/sh
>
> # List of files we are looking to copy from
> SRC="drivers/serial/"
> # Temporary work directory
> DST=/tmp/work
> git-clone -l -n -s . $DST
> { cd $DST; git-symbolic-ref HEAD refs/heads/DELETEME; }
> for i in `git-rev-list v2.6.20..v2.6.24-rc6 -- $SRC`; do
>         j=`git-describe $i`
>         git-archive --prefix="$j/" $i -- $SRC | tar xf - -C $DST
>         # This is abusing the index, but it saves space...
>         { cd $DST; git add $j; rm -rf $j; }
> done
>
> # And  now proceed as per Linus's idea...
> # Except we have it all in the index; no need
> # to actually make a commit...
>
> cd $DST
> cp $target_file $DST
> { cd $DST; git-diff-files -M...; }

I tried this using -M1%, it returned 53,575 files. Same thing for 10%.

The files don't seem to be in order by similarity, the first match
returned is not a good one.

I attached the file if anyone wants to play with it. I'm 90% certain
it was copied from amba-pl010.c in 2.6.15.


>
>
> Maybe a real git wizard will show me how to insert the index entries
> directly without ever doing anything as pedestrian as extracting, hashing,
> and then deleting the files, but it's still not that bad.
>
> And it's kind of a neat example of using the index as a staging area
> for a commit.
>
> (Exercise for the reader: the above gets a complete copy of every file in
> the directory for every commit in qhich ANY file in the directory changed.
> Better would be to do the git-rev-list per-file, so you only add unique
> file versions.  This requires an outer loop over file names and a more
> careful pathname specification to git add in the inner loop.)
>


-- 
Jon Smirl
jonsmirl@gmail.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: ep93xx_uart.c --]
[-- Type: text/x-csrc; name=ep93xx_uart.c, Size: 23091 bytes --]

/*
 *  linux/drivers/serial/cs93xx.c
 *
 *  Driver for EP93xx serial ports
 *
 *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o,
 *  Deep Blue Solutions Ltd.
 *
 *  Copyright 1999 ARM Limited
 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
 *  Copyright (c) 2003 Cirrus Logic, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  $Id: linux-2.6.21.5-ep9x.patch,v 1.8 2008/01/04 13:28:07 baustin Exp $
 *
 * The EP93xx serial ports are AMBA, but at different addresses from the
 * integrator.
 * This is a generic driver for ARM AMBA-type serial ports.  They
 * have a lot of 16550-like features, but are not register compatable.
 * Note that although they do have CTS, DCD and DSR inputs, they do
 * not have an RI input, nor do they have DTR or RTS outputs.  If
 * required, these have to be supplied via some other means (eg, GPIO)
 * and hooked into this driver.
 */
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/spinlock.h>
//#include <linux/device.h>
#include <linux/platform_device.h>

#include <asm/hardware.h>
#include <asm/io.h>
//#include <asm/irqs.h>

#if defined(CONFIG_SERIAL_EP93XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif


#include <linux/serial_core.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>



#if defined(CONFIG_ARCH_EP9301) || defined(CONFIG_ARCH_EP9302)
#ifdef CONFIG_EP93XX_IRDA
#define UART_NR		1
#else
#define UART_NR		2
#endif
#else
#ifdef CONFIG_EP93XX_IRDA
#define UART_NR		2
#else
#define UART_NR		3
#endif
#endif

#define SERIAL_EP93XX_MAJOR	204
#define SERIAL_EP93XX_MINOR	16
#define SERIAL_EP93XX_NR	UART_NR

#define EP93XX_ISR_PASS_LIMIT	256

/*
 * Access macros for the AMBA UARTs
 */
#define UART_GET_INT_STATUS(p)	((readl((p)->membase + UARTIIR)) & 0xff)
#define UART_PUT_ICR(p, c)	writel((c), (p)->membase + UARTICR)
#define UART_GET_FR(p)		((readl((p)->membase + UARTFR)) & 0xff)
#define UART_GET_CHAR(p)	((readl((p)->membase + UARTDR)) & 0xff)
#define UART_PUT_CHAR(p, c)	writel((c), (p)->membase + UARTDR)
#define UART_GET_RSR(p)		((readl((p)->membase + UARTRSR)) & 0xff)
#define UART_PUT_RSR(p, c)	writel((c), (p)->membase + UARTRSR)
#define UART_GET_CR(p)		((readl((p)->membase + UARTCR)) & 0xff)
#define UART_PUT_CR(p,c)	writel((c), (p)->membase + UARTCR)
#define UART_GET_LCRL(p)	((readl((p)->membase + UARTCR_L)) & 0xff)
#define UART_PUT_LCRL(p,c)	writel((c), (p)->membase + UARTCR_L)
#define UART_GET_LCRM(p)	((readl((p)->membase + UARTCR_M)) & 0xff)
#define UART_PUT_LCRM(p,c)	writel((c), (p)->membase + UARTCR_M)
#define UART_GET_LCRH(p)	((readl((p)->membase + UARTCR_H)) & 0xff)
#define UART_PUT_LCRH(p,c)	writel((c), (p)->membase + UARTCR_H)
#define UART_RX_DATA(s)		(((s) & UARTFR_RXFE) == 0)
#define UART_TX_READY(s)	(((s) & UARTFR_TXFF) == 0)
#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & UARTFR_TMSK) == 0)

#define UART_GET_MCR(p)		readl((p)->membase + UARTMCR)
#define UART_PUT_MCR(c, p)	writel((c), (p)->membase + UARTMCR)
#define UART_CLEAR_ECR(p)	writel( 0, (p)->membase + UARTECR)

#define UART_DUMMY_RSR_RX	256
#define UART_PORT_SIZE		65536

/*
 * We wrap our port structure around the generic uart_port.
 */
struct uart_ep93xx_port {
	struct uart_port	port;
	unsigned int		old_status;
};


static void
ep93xxuart_enable_clocks(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	/*
	 * Enable the clocks to this UART in CSC_syscon
	 * - Read DEVCFG
	 * - OR in the correct uart enable bit
	 * - Set the lock register
	 * - Write back to DEVCFG
	 */
	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U1EN;
		break;

	case UART2_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U2EN;
		break;

	case UART3_BASE:
		uiSysDevCfg |= SYSCON_DEVCFG_U3EN;
		break;
	}

	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
}

static void
ep93xxuart_disable_clocks(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	/*
	 * Disable the clocks to this UART in CSC_syscon
	 * - Read DEVCFG
	 * - AND to clear the correct uart enable bit
	 * - Set the lock register
	 * - Write back to DEVCFG
	 */
	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U1EN);
		break;

	case UART2_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U2EN);
		break;

	case UART3_BASE:
		uiSysDevCfg &= ~((unsigned int)SYSCON_DEVCFG_U3EN);
		break;
	}

	SysconSetLocked( SYSCON_DEVCFG, uiSysDevCfg );
}

#if 1
static int
ep93xxuart_is_port_enabled(struct uart_port *port)
{
	unsigned int uiSysDevCfg;

	uiSysDevCfg = inl(SYSCON_DEVCFG);

	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U1EN;
		break;

	case UART2_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U2EN;
		break;

	case UART3_BASE:
		uiSysDevCfg &= (unsigned int)SYSCON_DEVCFG_U3EN;
		break;
	}

	return( uiSysDevCfg != 0 );
}
#endif

static void
ep93xxuart_stop_tx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr &= ~UARTCR_TIE;
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_start_tx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr |= UARTCR_TIE;
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_stop_rx(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr &= ~(UARTCR_RIE | UARTCR_RTIE);
	UART_PUT_CR(port, cr);
}

static void
ep93xxuart_enable_ms(struct uart_port *port)
{
	unsigned int cr;

	cr = UART_GET_CR(port);
	cr |= UARTCR_MSIE;
	UART_PUT_CR(port, cr);
}

static void
#ifdef SUPPORT_SYSRQ
ep93xxuart_rx_chars(struct uart_port *port, struct pt_regs *regs)
#else
ep93xxuart_rx_chars(struct uart_port *port)
#endif
{
	struct tty_struct *tty = port->info->tty;
	unsigned int status, ch, flag, rsr, max_count = 256;

if(((unsigned long)port->membase)==UART2_BASE)
{
printk("ep93 UART2 ep93xxuart_rx_chars\n");
}

	flag = 0;
	status = UART_GET_FR(port);
	while (UART_RX_DATA(status) && max_count--) {
		//if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
		//	tty->flip.work.func((void *)tty);
		//	if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
		//		printk(KERN_WARNING "TTY_DONT_FLIP set\n");
		//		return;
		//	}
		//}
		
		ch = UART_GET_CHAR(port);

		//*tty->flip.char_buf_ptr = ch;
		//*tty->flip.flag_buf_ptr = TTY_NORMAL;
		port->icount.rx++;

		/*
		 * Note that the error handling code is
		 * out of the main execution path
		 */
		rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
		UART_PUT_RSR(port, 0);
		if (rsr & UARTRSR_ANY) {
			if (rsr & UARTRSR_BE) {
				rsr &= ~(UARTRSR_FE | UARTRSR_PE);
				port->icount.brk++;
				if (uart_handle_break(port))
					goto ignore_char;
			} else if (rsr & UARTRSR_PE)
				port->icount.parity++;
			else if (rsr & UARTRSR_FE)
				port->icount.frame++;
			if (rsr & UARTRSR_OE)
				port->icount.overrun++;

			rsr &= port->read_status_mask;

			if (rsr & UARTRSR_BE)
				//*tty->flip.flag_buf_ptr = TTY_BREAK;
				flag = TTY_BREAK;
			else if (rsr & UARTRSR_PE)
				//*tty->flip.flag_buf_ptr = TTY_PARITY;
				flag = TTY_PARITY;
			else if (rsr & UARTRSR_FE)
				//*tty->flip.flag_buf_ptr = TTY_FRAME;
				flag = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, ch))
			goto ignore_char;

		//if ((rsr & port->ignore_status_mask) == 0) {
		//	tty->flip.flag_buf_ptr++;
		//	tty->flip.char_buf_ptr++;
		//	tty->flip.count++;
		//}
		//if ((rsr & UARTRSR_OE) &&
		//   tty->flip.count < TTY_FLIPBUF_SIZE) {
			/*
			 * Overrun is special, since it's reported
			 * immediately, and doesn't affect the current
			 * character
			 */
		//	*tty->flip.char_buf_ptr++ = 0;
		//	*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
		//	tty->flip.count++;
		//}

		uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);

	ignore_char:
		status = UART_GET_FR(port);
	}
	tty_flip_buffer_push(tty);
	return;
}

static void
ep93xxuart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->info->xmit;
	int count;

	if (port->x_char) {
		UART_PUT_CHAR(port, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}
	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		ep93xxuart_stop_tx(port);
		return;
	}

	count = port->fifosize >> 1;
	do {
		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	} while (--count > 0);

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit))
		ep93xxuart_stop_tx(port);
}

static void
ep93xxuart_modem_status(struct uart_port *port)
{
	struct uart_ep93xx_port *uap = (struct uart_ep93xx_port *)port;
	unsigned int status, delta;

	UART_PUT_ICR(port, 0);

	status = UART_GET_FR(port) & UARTFR_MODEM_ANY;

	delta = status ^ uap->old_status;
	uap->old_status = status;

	if (!delta)
		return;

	if (delta & UARTFR_DCD)
		uart_handle_dcd_change(port, status & UARTFR_DCD);

	if (delta & UARTFR_DSR)
		port->icount.dsr++;

	if (delta & UARTFR_CTS)
		uart_handle_cts_change(port, status & UARTFR_CTS);

	wake_up_interruptible(&port->info->delta_msr_wait);
}

static irqreturn_t
ep93xxuart_int(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	unsigned int status, pass_counter = EP93XX_ISR_PASS_LIMIT;


if(((unsigned long)port->membase)==UART2_BASE)
{
printk("ep93 UART2 ep93xxuart_int\n");
}


	spin_lock(&port->lock);

	status = UART_GET_INT_STATUS(port);
if(((unsigned long)port->membase)==UART2_BASE)
{
printk("status=%x\n",status);
}
	do {
		if (status & (UARTIIR_RTIS | UARTIIR_RIS))
#ifdef SUPPORT_SYSRQ
			ep93xxuart_rx_chars(port, regs);
#else
			ep93xxuart_rx_chars(port);
#endif
		if (status & UARTIIR_TIS)
			ep93xxuart_tx_chars(port);
		if (status & UARTIIR_MIS)
			ep93xxuart_modem_status(port);

		if (pass_counter-- == 0)
			break;

		status = UART_GET_INT_STATUS(port);
	} while (status & (UARTIIR_RTIS | UARTIIR_RIS | UARTIIR_TIS));

	spin_unlock(&port->lock);

	return IRQ_HANDLED;
}

static unsigned int
ep93xxuart_tx_empty(struct uart_port *port)
{
	return UART_GET_FR(port) & UARTFR_BUSY ? 0 : TIOCSER_TEMT;
}

static unsigned int
ep93xxuart_get_mctrl(struct uart_port *port)
{
	unsigned int result = 0;
	unsigned int status;

	status = UART_GET_FR(port);
	if (status & UARTFR_DCD)
		result |= TIOCM_CAR;
	if (status & UARTFR_DSR)
		result |= TIOCM_DSR;
	if (status & UARTFR_CTS)
		result |= TIOCM_CTS;

	return result;
}

static void
ep93xxuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	unsigned int ctrl = 0;

	ctrl = UART_GET_MCR(port);

#define BIT93(tiocmbit, uartbit)		\
	if (mctrl & tiocmbit)		\
		ctrl |= uartbit;	\
	else				\
		ctrl &= ~uartbit

	BIT93(TIOCM_RTS, UARTMCR_RTS);
	BIT93(TIOCM_DTR, UARTMCR_DTR);
	BIT93(TIOCM_OUT1, UARTMCR_OUT1);
	BIT93(TIOCM_OUT2, UARTMCR_OUT2);
	BIT93(TIOCM_LOOP, UARTMCR_LOOP);
#undef BIT93

	UART_PUT_MCR(ctrl, port);
}

static void
ep93xxuart_break_ctl(struct uart_port *port, int break_state)
{
	unsigned long flags;
	unsigned int lcr_h;

	spin_lock_irqsave(&port->lock, flags);
	lcr_h = UART_GET_LCRH(port);
	if (break_state == -1)
		lcr_h |= UARTLCR_H_BRK;
	else
		lcr_h &= ~UARTLCR_H_BRK;
	UART_PUT_LCRH(port, lcr_h);
	spin_unlock_irqrestore(&port->lock, flags);
}

static int
ep93xxuart_startup(struct uart_port *port)
{
	struct uart_ep93xx_port *uap = (struct uart_ep93xx_port *)port;
	int retval = -EINVAL;
	char *name = 0;

	/*
	 * Enable the clocks for this port.
	 */
	ep93xxuart_enable_clocks(port);

	/*
	 * Get the name of this port (used only for resource allocations).
	 */
	switch ((unsigned long)port->membase) {
	case UART1_BASE:
		name = "ttyAM0";
		break;
	case UART2_BASE:
		name = "ttyAM1";
		break;
	case UART3_BASE:
		name = "ttyAM2";
		break;
	}
printk("EP93XX UART--%s irq=%d\n",name,port->irq);
	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(port->irq, ep93xxuart_int, 0 , name, port);
printk("irq is ok %d\n",retval);
	if (retval) {
		ep93xxuart_disable_clocks(port);
		return retval;
	}

	/*
	 * Allocate the memory region.
	 */
	if(request_mem_region(port->mapbase, UART_PORT_SIZE, name) == NULL) {
		printk("mem region fail\n");
		free_irq(port->irq, port);
		ep93xxuart_disable_clocks(port);
		return 1;
	}

	/*
	 * initialise the old status of the modem signals
	 */
	uap->old_status = UART_GET_FR(port) & UARTFR_MODEM_ANY;

printk("old status %x\n",uap->old_status);
	/*
	 * Finally, enable interrupts
	 */
	spin_lock_irq(&port->lock);
	UART_PUT_CR(port, UARTCR_UARTEN | UARTCR_RIE | UARTCR_RTIE|0x2);
	spin_unlock_irq(&port->lock);
	
	{
	unsigned int cr;

	cr = UART_GET_CR(port);
	printk("cr=%x\n",cr);
	}
	/*
	 * Success.
	 */
	return 0;
}

static void
ep93xxuart_shutdown(struct uart_port *port)
{
	/*
	 * disable all interrupts, disable the port
	 */
	UART_PUT_CR(port, 0);

	/*
	 * disable break condition and fifos
	 */
	UART_PUT_LCRH(port, UART_GET_LCRH(port) &
		      ~(UARTLCR_H_BRK | UARTLCR_H_FEN));

	/*
	 * Free the interrupt
	 */
	free_irq(port->irq, port);

	/*
	 * Release the memory region.
	 */
	release_mem_region(port->mapbase, UART_PORT_SIZE);

	/*
	 * Disable the clock.
	 */
	ep93xxuart_disable_clocks( port );
}

static void
ep93xxuart_set_termios(struct uart_port *port, struct ktermios *termios,
		       struct ktermios *old)
{
	unsigned int lcr_h, baud, quot;
	unsigned long flags;

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
	quot = uart_get_divisor(port, baud) - 1;
	
	/* byte size and parity */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		lcr_h = UARTLCR_H_WLEN_5;
		break;
	case CS6:
		lcr_h = UARTLCR_H_WLEN_6;
		break;
	case CS7:
		lcr_h = UARTLCR_H_WLEN_7;
		break;
	default: // CS8
		lcr_h = UARTLCR_H_WLEN_8;
		break;
	}
	if (termios->c_cflag & CSTOPB)
		lcr_h |= UARTLCR_H_STP2;
	if (termios->c_cflag & PARENB) {
		lcr_h |= UARTLCR_H_PEN;
		if (!(termios->c_cflag & PARODD))
			lcr_h |= UARTLCR_H_EPS;
	}
	if (port->fifosize > 1)
		lcr_h |= UARTLCR_H_FEN;

	spin_lock_irqsave(&port->lock, flags);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	port->read_status_mask = UARTRSR_OE;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UARTRSR_FE | UARTRSR_PE;
	if (termios->c_iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UARTRSR_BE;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= UARTRSR_FE | UARTRSR_PE;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= UARTRSR_BE;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= UARTRSR_OE;
	}

	/*
	 * Ignore all characters if CREAD is not set.
	 */
	if ((termios->c_cflag & CREAD) == 0)
		port->ignore_status_mask |= UART_DUMMY_RSR_RX;

	if (UART_ENABLE_MS(port, termios->c_cflag))
		ep93xxuart_enable_ms(port);

	UART_PUT_LCRL(port, quot & 0xff);
	UART_PUT_LCRM(port, (quot >> 8) & 0xff);
	UART_PUT_LCRH(port, lcr_h);

	spin_unlock_irqrestore(&port->lock, flags);
}

static const char *
ep93xxuart_type(struct uart_port *port)
{
	return port->type == PORT_AMBA ? "EP93XX" : NULL;
}

/*
 * Release the memory region(s) being used by 'port'
 */
static void
ep93xxuart_release_port(struct uart_port *port)
{
}

/*
 * Request the memory region(s) being used by 'port'
 */
static int
ep93xxuart_request_port(struct uart_port *port)
{
	return 0;
}

/*
 * Configure/autoconfigure the port.
 */
static void
ep93xxuart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE)
		port->type = PORT_AMBA;
}

/*
 * verify the new serial_struct (for TIOCSSERIAL).
 */
static int
ep93xxuart_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	int ret = 0;
	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
		ret = -EINVAL;
	if (ser->irq < 0 || ser->irq >= NR_IRQS)
		ret = -EINVAL;
	if (ser->baud_base < 9600)
		ret = -EINVAL;
	return ret;
}

static struct uart_ops ep93xx_pops = {
	.tx_empty	= ep93xxuart_tx_empty,
	.set_mctrl	= ep93xxuart_set_mctrl,
	.get_mctrl	= ep93xxuart_get_mctrl,
	.stop_tx	= ep93xxuart_stop_tx,
	.start_tx	= ep93xxuart_start_tx,
	.stop_rx	= ep93xxuart_stop_rx,
	.enable_ms	= ep93xxuart_enable_ms,
	.break_ctl	= ep93xxuart_break_ctl,
	.startup	= ep93xxuart_startup,
	.shutdown	= ep93xxuart_shutdown,
	.set_termios	= ep93xxuart_set_termios,
	.type		= ep93xxuart_type,
	.release_port	= ep93xxuart_release_port,
	.request_port	= ep93xxuart_request_port,
	.config_port	= ep93xxuart_config_port,
	.verify_port	= ep93xxuart_verify_port,
};

static struct uart_ep93xx_port ep93xx_ports[UART_NR] = {
	{
		.port	= {
			.membase	= (void *)UART1_BASE,
			.mapbase	= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART1,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 0,
		},
	},
#if !defined(CONFIG_EP93XX_IRDA)
	{
		.port	= {
			.membase	= (void *)UART2_BASE,
			.mapbase	= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART2,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
			.line		= 1,
		},
	},
#endif
#if !defined(CONFIG_ARCH_EP9301) && !defined(CONFIG_ARCH_EP9302)
	{
		.port	= {
			.membase	= (void *)UART3_BASE,
			.mapbase	= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT,
			.iotype		= UPIO_MEM,
			.irq		= IRQ_EP93XX_UART3,
			.uartclk	= 14745600,
			.fifosize	= 16,
			.ops		= &ep93xx_pops,
			.flags		= UPF_BOOT_AUTOCONF,
#if !defined(CONFIG_EP93XX_IRDA)
			.line		= 2,
#else
			.line		= 1,
#endif
		},
	}
#endif
};

#ifdef CONFIG_SERIAL_EP93XX_CONSOLE

static void
ep93xxuart_console_write_char(struct uart_port *port, char ch)
{
	unsigned int status;

	do {
		status = UART_GET_FR(port);
	} while (!UART_TX_READY(status));
	UART_PUT_CHAR(port, ch);
}

static void
ep93xxuart_console_write(struct console *co, const char *s, unsigned int count)
{
	struct uart_port *port = &ep93xx_ports[co->index].port;
	unsigned int status, old_cr, old_power;
	int i;

	old_power = ep93xxuart_is_port_enabled(port);
	if (!old_power)
		ep93xxuart_enable_clocks(port);

	/*
	 * First save the CR then disable the interrupts
	 */
	old_cr = UART_GET_CR(port);
	UART_PUT_CR(port, UARTCR_UARTEN);

	/*
	 * Now, do each character
	 */
	for (i = 0; i < count; i++) {
		ep93xxuart_console_write_char(port, s[i]);
		if (s[i] == '\n')
			ep93xxuart_console_write_char(port, '\r');
	}

	/*
	 * Finally, wait for transmitter to become empty
	 * and restore the TCR
	 */
	do {
		status = UART_GET_FR(port);
	} while (status & UARTFR_BUSY);
	UART_PUT_CR(port, old_cr);

	if (!old_power)
		ep93xxuart_disable_clocks(port);
}

static void __init
ep93xxuart_console_get_options(struct uart_port *port, int *baud, int *parity,
			       int *bits)
{
	if (UART_GET_CR(port) & UARTCR_UARTEN) {
		unsigned int lcr_h, lcr_m, lcr_l;

		lcr_h = UART_GET_LCRH(port);

		*parity = 'n';
		if (lcr_h & UARTLCR_H_PEN) {
			if (lcr_h & UARTLCR_H_EPS)
				*parity = 'e';
			else
				*parity = 'o';
		}

		if ((lcr_h & 0x60) == UARTLCR_H_WLEN_7)
			*bits = 7;
		else
			*bits = 8;

		lcr_m = UART_GET_LCRM(port);
		lcr_l = UART_GET_LCRL(port);

		*baud = port->uartclk / (16 * ((lcr_m * 256) + lcr_l + 1));
	}
}

static int __init
ep93xxuart_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	int baud = 57600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	/*
	 * Check whether an invalid uart number has been specified, and
	 * if so, search for the first available port that does have
	 * console support.
	 */
	if (co->index >= UART_NR)
		co->index = 0;
	port = &ep93xx_ports[co->index].port;

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	else
		ep93xxuart_console_get_options(port, &baud, &parity, &bits);

	return uart_set_options(port, co, baud, parity, bits, flow);
}

static struct console ep93xx_console;
#define EP93XX_CONSOLE	&ep93xx_console
#else
#define EP93XX_CONSOLE	NULL
#endif

static struct uart_driver ep93xx_reg = {
	.driver_name		= "ttyAM",
	.dev_name		= "ttyAM",
	.major			= SERIAL_EP93XX_MAJOR,
	.minor			= SERIAL_EP93XX_MINOR,
	.nr			= UART_NR,
	.cons			= EP93XX_CONSOLE,
};


/*
 * The 'index' element of this field selects which UART to use for
 * console.  For ep93xx, valid values are 0, 1, and 2.  If you set
 * it to -1, then uart_get_console will search for the first UART
 * which is the same as setting it to 0.
 */
static struct console ep93xx_console = {
	.name		= "ttyAM",
	.write		= ep93xxuart_console_write,
	.device		= uart_console_device,
	.setup		= ep93xxuart_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &ep93xx_reg,
};

static int __init
ep93xxuart_console_init(void)
{
	register_console(&ep93xx_console);
	return 0;
}
console_initcall(ep93xxuart_console_init);

static struct resource uarts[UART_NR] = {
	[0] = {
		.name		= "uart1",
		.start		= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT,
		.end		= /*HwRegToPhys(UART1_BASE)*/UART1_BASE_VIRT + 0x0000ffff,
	},
#if !defined(CONFIG_EP93XX_IRDA)
	[1] = {
		.name		= "uart2",
		.start		= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT,
		.end		= /*HwRegToPhys(UART2_BASE)*/UART2_BASE_VIRT + 0x0000ffff,
	},
#endif
#if !defined(CONFIG_ARCH_EP9301) && !defined(CONFIG_ARCH_EP9302)
	[2] = {
		.name		= "uart3",
		.start		= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT,
		.end		= /*HwRegToPhys(UART3_BASE)*/UART3_BASE_VIRT + 0x0000ffff,
	},
#endif
};

static int __init
ep93xxuart_init(void)
{
	int ret, i;

	ret = uart_register_driver(&ep93xx_reg);
	if (ret == 0) {
		for (i = 0; i < UART_NR; i++) {
			request_resource(&iomem_resource, &uarts[i]);
			uart_add_one_port(&ep93xx_reg, &ep93xx_ports[i].port);
		}
	}
	return ret;
}

static void __exit ep93xxuart_exit(void)
{
	int i;

	for (i = 0; i < UART_NR; i++)
		uart_remove_one_port(&ep93xx_reg, &ep93xx_ports[i].port);
	uart_unregister_driver(&ep93xx_reg);
}

module_init(ep93xxuart_init);
module_exit(ep93xxuart_exit);

MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd/Cirrus Logic, Inc.");
MODULE_DESCRIPTION("EP93xx ARM serial port driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(SERIAL_EP93XX_MAJOR, SERIAL_EP93XX_MINOR);

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
  2008-01-13 16:28 linux
  2008-01-13 17:04 ` Jon Smirl
  2008-01-13 17:31 ` Jon Smirl
@ 2008-01-14 12:08 ` Jeff King
  2008-01-14 14:49   ` Jon Smirl
  2 siblings, 1 reply; 7+ messages in thread
From: Jeff King @ 2008-01-14 12:08 UTC (permalink / raw)
  To: linux; +Cc: git, jonsmirl, torvalds

On Sun, Jan 13, 2008 at 11:28:06AM -0500, linux@horizon.com wrote:

> Maybe a real git wizard will show me how to insert the index entries
> directly without ever doing anything as pedestrian as extracting, hashing,
> and then deleting the files, but it's still not that bad.

git-read-tree?  Unfortunately it has no option to insert only a subset
of the tree. But you can make do with git-ls-tree piped to
git-update-index.

Using the script below, Jon's sample file seems to be

  v2.6.15-rc6-81-g0b57ee9:drivers/serial/amba-pl010.c

and it runs in about 8 seconds on v2.6.13..v2.6.15. I think it might be
more intuitive to just diff a temporary index against each tree, but I
don't think there's a way to say "find copies harder, but use only this
subset of files as the source" which makes it less efficient.

Jon, you might try playing around with different ranges. I get a
different answer for v2.6.13..v2.6.16.

-- >8 --
SRC=drivers/serial

echo >&2 Cleaning up after old runs...
rm -f tmpindex
git branch -D tmpbranch

echo >&2 Creating giant source commit...
for i in `git rev-list v2.6.13..v2.6.15 -- $SRC`; do
  git ls-tree -r $i -- $SRC |
    # note the whitespace is a literal tab
    sed "s,	,	$i/," |
    GIT_INDEX_FILE=tmpindex git update-index --index-info
done
tree=`GIT_INDEX_FILE=tmpindex git write-tree`
commit=`echo source | git commit-tree $tree`
git update-ref refs/heads/tmpbranch $commit

echo >&2 Creating updated index...
GIT_INDEX_FILE=tmpindex git add candidate.c
echo >&2 Diffing...
GIT_INDEX_FILE=tmpindex git diff-index --cached -l0 -M1% -C1% --find-copies-harder tmpbranch

# now you should manually git-describe the winner

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Digging through old vendor code
  2008-01-14 12:08 ` Jeff King
@ 2008-01-14 14:49   ` Jon Smirl
  0 siblings, 0 replies; 7+ messages in thread
From: Jon Smirl @ 2008-01-14 14:49 UTC (permalink / raw)
  To: Jeff King; +Cc: linux, git, torvalds

On 1/14/08, Jeff King <peff@peff.net> wrote:
> On Sun, Jan 13, 2008 at 11:28:06AM -0500, linux@horizon.com wrote:
>
> > Maybe a real git wizard will show me how to insert the index entries
> > directly without ever doing anything as pedestrian as extracting, hashing,
> > and then deleting the files, but it's still not that bad.
>
> git-read-tree?  Unfortunately it has no option to insert only a subset
> of the tree. But you can make do with git-ls-tree piped to
> git-update-index.
>
> Using the script below, Jon's sample file seems to be
>
>   v2.6.15-rc6-81-g0b57ee9:drivers/serial/amba-pl010.c
>
> and it runs in about 8 seconds on v2.6.13..v2.6.15. I think it might be
> more intuitive to just diff a temporary index against each tree, but I
> don't think there's a way to say "find copies harder, but use only this
> subset of files as the source" which makes it less efficient.
>
> Jon, you might try playing around with different ranges. I get a
> different answer for v2.6.13..v2.6.16.

That's probably because some of the other drivers in there were also
created via copy and edit. The similarity between drivers is what made
the original base hard to find. amba-pl010.c is probably a copy/edit
from one of the other drivers.

I'm pretty sure 2.6.15/amba-pl010.c is right. I started undoing some
of the obvious changes like renaming the functions and the diffs are
getting pretty small.

Thanks for the help on this. I have enough info now to separate the diffs.

This would probably make a nice command to add to git since I'm sure
other vendors have done copy/edit to make their out of tree drivers. I
doubt if any other SCM has a command like this.

I'm really starting to hate the "port and forget" that goes on in the
embedded world. But I'm beginning to understand why it happens. I've
been working since November to get a patch  into i2c without success -
19 versions. The process is chewing up way too much time relative to
the importance of the patch to my code. So I'm just about ready to
"port and forget" the patch.

>
> -- >8 --
> SRC=drivers/serial
>
> echo >&2 Cleaning up after old runs...
> rm -f tmpindex
> git branch -D tmpbranch
>
> echo >&2 Creating giant source commit...
> for i in `git rev-list v2.6.13..v2.6.15 -- $SRC`; do
>   git ls-tree -r $i -- $SRC |
>     # note the whitespace is a literal tab
>     sed "s,     ,       $i/," |
>     GIT_INDEX_FILE=tmpindex git update-index --index-info
> done
> tree=`GIT_INDEX_FILE=tmpindex git write-tree`
> commit=`echo source | git commit-tree $tree`
> git update-ref refs/heads/tmpbranch $commit
>
> echo >&2 Creating updated index...
> GIT_INDEX_FILE=tmpindex git add candidate.c
> echo >&2 Diffing...
> GIT_INDEX_FILE=tmpindex git diff-index --cached -l0 -M1% -C1% --find-copies-harder tmpbranch
>
> # now you should manually git-describe the winner
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-01-14 14:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-13  4:09 Digging through old vendor code Jon Smirl
2008-01-13  4:41 ` Linus Torvalds
  -- strict thread matches above, loose matches on Subject: below --
2008-01-13 16:28 linux
2008-01-13 17:04 ` Jon Smirl
2008-01-13 17:31 ` Jon Smirl
2008-01-14 12:08 ` Jeff King
2008-01-14 14:49   ` Jon Smirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).