Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Marc St-Jean <stjeanma@pmc-sierra.com>
Cc: ralf@linux-mips.org, linux-mips@linux-mips.org
Subject: Re: [PATCH 7/12] drivers: PMC MSP71xx GPIO char driver
Date: Tue, 19 Jun 2007 14:12:56 -0700	[thread overview]
Message-ID: <20070619141256.3d573a41.akpm@linux-foundation.org> (raw)
In-Reply-To: <200706152046.l5FKk3NU015608@pasqua.pmc-sierra.bc.ca>

On Fri, 15 Jun 2007 14:46:03 -0600
Marc St-Jean <stjeanma@pmc-sierra.com> wrote:

> [PATCH 7/12] drivers: PMC MSP71xx GPIO char driver
> 
> Patch to add a GPIO char driver for the PMC-Sierra MSP71xx devices.


> +const u32 GPIO_DATA_COUNT[] = { 2, 4, 4, 6 };
> +const u32 GPIO_DATA_SHIFT[] = { 0, 2, 6, 10 };
> +const u32 GPIO_DATA_MASK[] = { 0x03, 0x0f, 0x0f, 0x3f };
> +u32 * const GPIO_DATA_REG[] = {
> +	(u32 *)GPIO_DATA1_REG, (u32 *)GPIO_DATA2_REG,
> +	(u32 *)GPIO_DATA3_REG, (u32 *)GPIO_DATA4_REG,
> +};
> +const u32 GPIO_CFG_MASK[] = { 0x0000ff, 0x00ffff, 0x00ffff, 0xffffff };
> +u32 * const GPIO_CFG_REG[] = {
> +	(u32 *)GPIO_CFG1_REG, (u32 *)GPIO_CFG2_REG,
> +	(u32 *)GPIO_CFG3_REG, (u32 *)GPIO_CFG4_REG,
> +};
> +
> +/* Maps MODE to allowed pin mask */
> +const u32 MSP_GPIO_MODE_ALLOWED[] = {
> +	0xfffff,	/* Mode 0 - INPUT */
> +	0x00000,	/* Mode 1 - INTERRUPT */
> +	0x00030,	/* Mode 2 - UART_INPUT (GPIO 4, 5)*/
> +	0, 0, 0, 0, 0,	/* Modes 3, 4, 5, 6, and 7 are reserved */
> +	0xfffff,	/* Mode 8 - OUTPUT */
> +	0x0000f,	/* Mode 9 - UART_OUTPUT/PERF_TIMERA (GPIO 0,1,2,3) */
> +	0x00003,	/* Mode a - PERF_TIMERB (GPIO 0, 1) */
> +	0x00000,	/* Mode b - Not really a mode! */
> +};

all the above should be lower-case and have static scope.

> +#define GPIO_CFG_SHIFT(i)	(i * 4)
> +#define GPIO_CFG_PINMASK	0xf
> +
> +/* The extended gpio register */
> +
> +#define EXTENDED_GPIO_COUNT	4
> +#define EXTENDED_GPIO_SHIFT	16
> +#define EXTENDED_GPIO_MASK	0x0f
> +
> +#define EXTENDED_GPIO_DATA_SHIFT(i)	(i * 2)
> +#define EXTENDED_GPIO_DATA_MASK(i)	(0x3 << (i*2))
> +#define EXTENDED_GPIO_DATA_SET		0x2
> +#define EXTENDED_GPIO_DATA_CLR		0x1
> +#define EXTENDED_GPIO_CFG_SHIFT(i)	((i * 2) + 16)
> +#define EXTENDED_GPIO_CFG_MASK(i)	(0x3 << ((i*2)+16))
> +#define EXTENDED_GPIO_CFG_DISABLE	0x2
> +#define EXTENDED_GPIO_CFG_ENABLE	0x1
> +
> +/* -- Data structures -- */
> +
> +static DEFINE_SPINLOCK(msp_gpio_spinlock);
> +
> +static struct task_struct *msp_blinkthread;
> +static DEFINE_SPINLOCK(msp_blink_lock);
> +static DECLARE_COMPLETION(msp_blink_wait);
> +
> +struct blink_table {
> +	u32 count;
> +	u32 period;
> +	u32 dcycle;
> +};
> +
> +static struct blink_table blink_table[MSP_NUM_GPIOS];
> +
> +/* -- Utility functions -- */
> +
> +/* Define the following for extra debug output */
> +#undef DEBUG

The under shouldn't be needed: -DDEBUG can be provided on the kbuild
command line.

> +#ifdef DEBUG
> +#define DBG(args...) printk(KERN_DEBUG args)
> +#else
> +#define DBG(args...) do {} while (0)
> +#endif
> +
> +/* Reads the data bits from a single register set */
> +static u32 msp_gpio_read_data_basic(int reg)
> +{
> +	return read_reg32(GPIO_DATA_REG[reg], GPIO_DATA_MASK[reg]);
> +}
> +
> +/* Reads the data bits from the extended register set */
> +static u32 msp_gpio_read_data_extended(void)
> +{
> +	int pin;
> +	u32 tmp = *EXTENDED_GPIO_REG;

`tmp' is always a bad name for a variable.

> +	u32 retval = 0;
> +	
> +	for (pin = 0; pin < EXTENDED_GPIO_COUNT; pin++) {
> +		u32 bit = 0;
> +		
> +		/*
> +		 * In output mode, read CLR bit
> +		 * In input mode, read SET bit
> +		 */
> +		if (tmp & (EXTENDED_GPIO_CFG_ENABLE <<
> +				EXTENDED_GPIO_CFG_SHIFT(pin)))
> +			bit = EXTENDED_GPIO_DATA_CLR <<
> +				EXTENDED_GPIO_DATA_SHIFT(pin);
> +		else
> +			bit = EXTENDED_GPIO_DATA_SET <<
> +				EXTENDED_GPIO_DATA_SHIFT(pin);
> +
> +		if (tmp & bit)
> +			retval |= 1 << pin;
> +	}
> +	
> +	return retval;
> +}
> +
> +/*
> + * Reads the current state of all 20 pins, putting the values in
> + * the lowest 20 bits (1=HI, 0=LO)
> + */
> +static u32 msp_gpio_read_data(void)
> +{
> +	int reg;
> +	u32 retval = 0;
> +	
> +	spin_lock(&msp_gpio_spinlock);
> +	for (reg = 0; reg < GPIO_REG_COUNT; reg++)
> +		retval |= msp_gpio_read_data_basic(reg) <<
> +				GPIO_DATA_SHIFT[reg];
> +	retval |= msp_gpio_read_data_extended() << EXTENDED_GPIO_SHIFT;
> +	spin_unlock(&msp_gpio_spinlock);
> +	
> +	DBG("%s: 0x%08x\n", __FUNCTION__, retval);
> +	return retval;
> +}
> +
>
> ...
>
> +/* Maps 'basic' pins to relative offset from 0 per register */
> +static int const MSP_GPIO_OFFSET[] = {
> +	/* GPIO 0 and 1 on the first register */
> +	0, 0,
> +	/* GPIO 2, 3, 4, and 5 on the second register */
> +	2, 2, 2, 2,
> +	/* GPIO 6, 7, 8, and 9 on the third register */
> +	6, 6, 6, 6,
> +	/* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
> +	10, 10, 10, 10, 10, 10,
> +};

This shouldn't be in a header file.  Because each compilation unit which
includes this header will (potentially) get its own copy of the data.

That includes any userspace apps which include this header(!)

> +/* This gives you the 'register relative ofet gpio' number */
> +#define OFFSET_GPIO_NUMBER(gpio)	(gpio - MSP_GPIO_OFFSET[gpio])
> +
> +/* These take the 'register relative offset gpio' number */
> +#define BASIC_MODE_REG_SHIFT(ogpio)	(ogpio * 4)
> +#define BASIC_MODE_REG_VALUE(mode, ogpio) \
> +			(mode << BASIC_MODE_REG_SHIFT(ogpio))
> +#define BASIC_MODE_REG_MASK(ogpio) \
> +			BASIC_MODE_REG_VALUE(0xf, ogpio)
> +#define BASIC_DATA_REG_MASK(ogpio)	(1 << ogpio)
> +
> +/* These take the actual GPIO number (0 through 15) */
> +#define BASIC_DATA_MASK(gpio) \
> +		BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
> +#define BASIC_MODE_MASK(gpio) \
> +		BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
> +#define BASIC_MODE(mode, gpio) \
> +		BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
> +#define BASIC_MODE_SHIFT(gpio) \
> +		BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
> +#define BASIC_MODE_FROM_REG(data, gpio)	\
> +		BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
> +
> +/* This gives you the 'register relative offset gpio' number */
> +#define EXTENDED_OFFSET_GPIO(gpio)	(gpio - 16)
> +
> +/* These take the 'register relative offset gpio' number */
> +#define EXTENDED_REG_DISABLE(ogpio)	(0x2 << ((ogpio * 2) + 16))
> +#define EXTENDED_REG_ENABLE(ogpio)	(0x1 << ((ogpio * 2) + 16))
> +#define EXTENDED_REG_SET(ogpio)		(0x2 << (ogpio * 2))
> +#define EXTENDED_REG_CLR(ogpio)		(0x1 << (ogpio * 2))
> +
> +/* These take the actual GPIO number (16 through 19) */
> +#define EXTENDED_DISABLE(gpio) \
> +		EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
> +#define EXTENDED_ENABLE(gpio) \
> +		EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
> +#define EXTENDED_SET(gpio) \
> +		EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
> +#define EXTENDED_CLR(gpio) \
> +		EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))

inlined functions are preferred over macros.  Only use macros when for some
reason you *must* use macros.

  reply	other threads:[~2007-06-19 21:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-15 20:46 [PATCH 7/12] drivers: PMC MSP71xx GPIO char driver Marc St-Jean
2007-06-19 21:12 ` Andrew Morton [this message]
2007-06-20  8:05   ` Ralf Baechle
  -- strict thread matches above, loose matches on Subject: below --
2007-06-20 22:54 Marc St-Jean
2007-06-20  0:27 Marc St-Jean
2007-06-20  3:25 ` Andrew Morton
2007-04-27 20:05 Marc St-Jean
2007-03-26 22:00 Marc St-Jean
2007-03-16 21:39 Marc St-Jean

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070619141256.3d573a41.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    --cc=stjeanma@pmc-sierra.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox