mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 00/12] Blackfin arch GPIO updating
@ 2007-08-08  3:35 Bryan Wu
  2007-08-08  3:35 ` [PATCH 01/12] Blackfin arch: add peripheral resource allocation support Bryan Wu
                   ` (11 more replies)
  0 siblings, 12 replies; 33+ messages in thread
From: Bryan Wu @ 2007-08-08  3:35 UTC (permalink / raw)
  To: torvalds, linux-kernel, akpm; +Cc: dbrownell

As David mentioned, I send out these series patch to LKML for review.
These patches are related Blackfin arch GPIO updating, not big change at all.
I think it is OK for git-pull in -RC2 or later.

Thanks
- Bryan Wu


^ permalink raw reply	[flat|nested] 33+ messages in thread
* RE: [PATCH 01/12] Blackfin arch: add peripheral resource allocation support
@ 2007-08-08  7:18 Hennerich, Michael
  2007-08-08  7:49 ` Bryan Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Hennerich, Michael @ 2007-08-08  7:18 UTC (permalink / raw)
  To: Bryan Wu, torvalds, linux-kernel, akpm; +Cc: dbrownell, Michael Hennerich

Bryan,

This patch doesn't seem to be up to date.
It doesn't include the changes made based on feedback from Joe Perches.

Please see our SVN:
Modified: trunk/arch/blackfin/kernel/bfin_gpio.c (3489 => 3490)

-Michael

>-----Original Message-----
>From: Bryan Wu [mailto:bryan.wu@analog.com]
>Sent: Mittwoch, 8. August 2007 05:35
>To: torvalds@linux-foundation.org; linux-kernel@vger.kernel.org;
>akpm@linux-foundation.org
>Cc: dbrownell@users.sourceforge.net; Michael Hennerich; Bryan Wu
>Subject: [PATCH 01/12] Blackfin arch: add peripheral resource
allocation
>support
>
>From: Michael Hennerich <michael.hennerich@analog.com>
>
>Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
>Signed-off-by: Bryan Wu <bryan.wu@analog.com>
>---
> arch/blackfin/kernel/bfin_gpio.c                  |  272
>++++++++++++++++++---
> include/asm-blackfin/mach-bf533/bfin_serial_5xx.h |   11 +-
> include/asm-blackfin/mach-bf537/bfin_serial_5xx.h |   23 +-
> include/asm-blackfin/mach-bf537/portmux.h         |    2 +-
> include/asm-blackfin/mach-bf561/bfin_serial_5xx.h |   11 +-
> 5 files changed, 274 insertions(+), 45 deletions(-)
>
>diff --git a/arch/blackfin/kernel/bfin_gpio.c
>b/arch/blackfin/kernel/bfin_gpio.c
>index bafcfa5..9f30948 100644
>--- a/arch/blackfin/kernel/bfin_gpio.c
>+++ b/arch/blackfin/kernel/bfin_gpio.c
>@@ -84,6 +84,7 @@
> #include <linux/err.h>
> #include <asm/blackfin.h>
> #include <asm/gpio.h>
>+#include <asm/portmux.h>
> #include <linux/irq.h>
>
> #ifdef BF533_FAMILY
>@@ -115,7 +116,11 @@ static struct gpio_port_t
>*gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
> };
> #endif
>
>-static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
>+static unsigned short
reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
>+static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS +
>16)];
>+char *str_ident = NULL;
>+
>+#define RESOURCE_LABEL_SIZE 16
>
> #ifdef CONFIG_PM
> static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
>@@ -143,13 +148,39 @@ inline int check_gpio(unsigned short gpio)
> 	return 0;
> }
>
>+static void set_label(unsigned short ident, const char *label)
>+{
>+
>+	if (label && str_ident) {
>+		strncpy(str_ident + ident * RESOURCE_LABEL_SIZE, label,
>+			 RESOURCE_LABEL_SIZE);
>+		str_ident[ident * RESOURCE_LABEL_SIZE +
>+			 RESOURCE_LABEL_SIZE - 1] = 0;
>+	}
>+}
>+
>+static char *get_label(unsigned short ident)
>+{
>+	if (!str_ident)
>+		return "UNKNOWN";
>+
>+	return (str_ident[ident * RESOURCE_LABEL_SIZE] ?
>+		(str_ident + ident * RESOURCE_LABEL_SIZE) : "UNKNOWN");
>+}
>+
>+static int cmp_label(unsigned short ident, const char *label)
>+{
>+	if (label && str_ident)
>+		return strncmp(str_ident + ident * RESOURCE_LABEL_SIZE,
>+				 label, strlen(label));
>+	else
>+		return -EINVAL;
>+}
>+
> #ifdef BF537_FAMILY
> static void port_setup(unsigned short gpio, unsigned short usage)
> {
> 	if (usage == GPIO_USAGE) {
>-		if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio))
>-			printk(KERN_WARNING "bfin-gpio: Possible
Conflict with
>Peripheral "
>-			       "usage and GPIO %d detected!\n", gpio);
> 		*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
> 	} else
> 		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
>@@ -159,6 +190,56 @@ static void port_setup(unsigned short gpio,
unsigned
>short usage)
> # define port_setup(...)  do { } while (0)
> #endif
>
>+#ifdef BF537_FAMILY
>+
>+#define PMUX_LUT_RES		0
>+#define PMUX_LUT_OFFSET		1
>+#define PMUX_LUT_ENTRIES	41
>+#define PMUX_LUT_SIZE		2
>+
>+static unsigned short port_mux_lut[PMUX_LUT_ENTRIES][PMUX_LUT_SIZE] =
{
>+	{P_PPI0_D13, 11}, {P_PPI0_D14, 11}, {P_PPI0_D15, 11},
>+	{P_SPORT1_TFS, 11}, {P_SPORT1_TSCLK, 11}, {P_SPORT1_DTPRI, 11},
>+	{P_PPI0_D10, 10}, {P_PPI0_D11, 10}, {P_PPI0_D12, 10},
>+	{P_SPORT1_RSCLK, 10}, {P_SPORT1_RFS, 10}, {P_SPORT1_DRPRI, 10},
>+	{P_PPI0_D8, 9}, {P_PPI0_D9, 9}, {P_SPORT1_DRSEC, 9},
>+	{P_SPORT1_DTSEC, 9}, {P_TMR2, 8}, {P_PPI0_FS3, 8}, {P_TMR3, 7},
>+	{P_SPI0_SSEL4, 7}, {P_TMR4, 6}, {P_SPI0_SSEL5, 6}, {P_TMR5, 5},
>+	{P_SPI0_SSEL6, 5}, {P_UART1_RX, 4}, {P_UART1_TX, 4}, {P_TMR6,
4},
>+	{P_TMR7, 4}, {P_UART0_RX, 3}, {P_UART0_TX, 3}, {P_DMAR0, 3},
>+	{P_DMAR1, 3}, {P_SPORT0_DTSEC, 1}, {P_SPORT0_DRSEC, 1},
>+	{P_CAN0_RX, 1}, {P_CAN0_TX, 1}, {P_SPI0_SSEL7, 1},
>+	{P_SPORT0_TFS, 0}, {P_SPORT0_DTPRI, 0}, {P_SPI0_SSEL2, 0},
>+	{P_SPI0_SSEL3, 0}
>+};
>+
>+static void portmux_setup(unsigned short per, unsigned short function)
>+{
>+	u16 y, muxreg, offset;
>+
>+	for (y = 0; y < PMUX_LUT_ENTRIES; y++) {
>+		if (port_mux_lut[y][PMUX_LUT_RES] == per) {
>+
>+			/* SET PORTMUX REG */
>+
>+			offset = port_mux_lut[y][PMUX_LUT_OFFSET];
>+			muxreg = bfin_read_PORT_MUX();
>+
>+			if (offset != 1) {
>+				muxreg &= ~(1 << offset);
>+			} else {
>+				muxreg &= ~(3 << 1);
>+			}
>+
>+			muxreg |= (function << offset);
>+			bfin_write_PORT_MUX(muxreg);
>+		}
>+	}
>+}
>+
>+#else
>+# define portmux_setup(...)  do { } while (0)
>+#endif
>
> static void default_gpio(unsigned short gpio)
> {
>@@ -179,22 +260,15 @@ static void default_gpio(unsigned short gpio)
>
> static int __init bfin_gpio_init(void)
> {
>-	int i;
>-
>-	printk(KERN_INFO "Blackfin GPIO Controller\n");
>
>-	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
>-		reserved_map[gpio_bank(i)] = 0;
>+	str_ident = kzalloc(RESOURCE_LABEL_SIZE * 256, GFP_KERNEL);
>+	if (!str_ident)
>+		return -ENOMEM;
>
>-#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) ||
>defined(CONFIG_BFIN_MAC_MODULE))
>-# if defined(CONFIG_BFIN_MAC_RMII)
>-	reserved_map[gpio_bank(PORT_H)] = 0xC373;
>-# else
>-	reserved_map[gpio_bank(PORT_H)] = 0xFFFF;
>-# endif
>-#endif
>+	printk(KERN_INFO "Blackfin GPIO Controller\n");
>
> 	return 0;
>+
> }
>
> arch_initcall(bfin_gpio_init);
>@@ -223,7 +297,7 @@ arch_initcall(bfin_gpio_init);
> void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
> { \
> 	unsigned long flags; \
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
\
> 	local_irq_save(flags); \
> 	if (arg) \
> 		gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
>@@ -243,7 +317,7 @@ SET_GPIO(both)
> #define SET_GPIO_SC(name) \
> void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
> { \
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
\
> 	if (arg) \
> 		gpio_bankb[gpio_bank(gpio)]->name ## _set =
gpio_bit(gpio); \
> 	else \
>@@ -258,7 +332,7 @@ SET_GPIO_SC(maskb)
> void set_gpio_data(unsigned short gpio, unsigned short arg)
> {
> 	unsigned long flags;
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
> 	local_irq_save(flags);
> 	if (arg)
> 		gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
>@@ -277,7 +351,7 @@ SET_GPIO_SC(data)
> void set_gpio_toggle(unsigned short gpio)
> {
> 	unsigned long flags;
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
> 	local_irq_save(flags);
> 	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
> 	bfin_read_CHIPID();
>@@ -286,7 +360,7 @@ void set_gpio_toggle(unsigned short gpio)
> #else
> void set_gpio_toggle(unsigned short gpio)
> {
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
> 	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
> }
> #endif
>@@ -350,7 +424,7 @@ unsigned short get_gpio_data(unsigned short gpio)
> {
> 	unsigned long flags;
> 	unsigned short ret;
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
> 	local_irq_save(flags);
> 	ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >>
gpio_sub_n(gpio));
> 	bfin_read_CHIPID();
>@@ -494,13 +568,14 @@ u32 gpio_pm_setup(void)
> 			gpio_bank_saved[bank].dir   =
gpio_bankb[bank]->dir;
> 			gpio_bank_saved[bank].edge  =
gpio_bankb[bank]->edge;
> 			gpio_bank_saved[bank].both  =
gpio_bankb[bank]->both;
>-			gpio_bank_saved[bank].reserved =
reserved_map[bank];
>+			gpio_bank_saved[bank].reserved =
>+						reserved_gpio_map[bank];
>
> 			gpio = i;
>
> 			while (mask) {
> 				if (mask & 1) {
>-					reserved_map[gpio_bank(gpio)] |=
>+
reserved_gpio_map[gpio_bank(gpio)] |=
> 							gpio_bit(gpio);
> 					bfin_gpio_wakeup_type(gpio,
> 						wakeup_flags_map[gpio]);
>@@ -540,7 +615,8 @@ void gpio_pm_restore(void)
> 			gpio_bankb[bank]->edge  =
gpio_bank_saved[bank].edge;
> 			gpio_bankb[bank]->both  =
gpio_bank_saved[bank].both;
>
>-			reserved_map[bank] =
gpio_bank_saved[bank].reserved;
>+			reserved_gpio_map[bank] =
>+					gpio_bank_saved[bank].reserved;
>
> 		}
>
>@@ -550,6 +626,140 @@ void gpio_pm_restore(void)
>
> #endif
>
>+
>+
>+
>+int peripheral_request(unsigned short per, const char *label)
>+{
>+	unsigned long flags;
>+	unsigned short ident = P_IDENT(per);
>+
>+	/*
>+	 * Don't cares are pins with only one dedicated function
>+	 */
>+
>+	if (per & P_DONTCARE)
>+		return 0;
>+
>+	if (!(per & P_DEFINED))
>+		return -ENODEV;
>+
>+	if (check_gpio(ident) < 0)
>+		return -EINVAL;
>+
>+	local_irq_save(flags);
>+
>+	if (unlikely(reserved_gpio_map[gpio_bank(ident)] &
gpio_bit(ident)))
>{
>+		printk(KERN_ERR
>+		       "%s: Peripheral %d is already reserved as GPIO by
%s
>!\n",
>+		       __FUNCTION__, ident, get_label(ident));
>+		dump_stack();
>+		local_irq_restore(flags);
>+		return -EBUSY;
>+	}
>+
>+	if (unlikely(reserved_peri_map[gpio_bank(ident)] &
gpio_bit(ident)))
>{
>+
>+	/*
>+	 * Pin functions like AMC address strobes my
>+	 * be requested and used by several drivers
>+	 */
>+
>+	if (!(per & P_MAYSHARE)) {
>+
>+	/*
>+	 * Allow that the identical pin function can
>+	 * be requested from the same driver twice
>+	 */
>+
>+		if (cmp_label(ident, label) == 0)
>+			goto anyway;
>+
>+			printk(KERN_ERR
>+			       "%s: Peripheral %d function %d is
already"
>+			       "reserved by %s !\n",
>+			       __FUNCTION__, ident, P_FUNCT2MUX(per),
>+				get_label(ident));
>+			dump_stack();
>+			local_irq_restore(flags);
>+			return -EBUSY;
>+		}
>+
>+	}
>+
>+anyway:
>+
>+
>+	portmux_setup(per, P_FUNCT2MUX(per));
>+
>+	port_setup(ident, PERIPHERAL_USAGE);
>+
>+	reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
>+	local_irq_restore(flags);
>+	set_label(ident, label);
>+
>+	return 0;
>+}
>+EXPORT_SYMBOL(peripheral_request);
>+
>+int peripheral_request_list(unsigned short per[], const char *label)
>+{
>+	u16 cnt;
>+	int ret;
>+
>+	for (cnt = 0; per[cnt] != 0; cnt++) {
>+		ret = peripheral_request(per[cnt], label);
>+		if (ret < 0)
>+			return ret;
>+	}
>+
>+	return 0;
>+}
>+EXPORT_SYMBOL(peripheral_request_list);
>+
>+void peripheral_free(unsigned short per)
>+{
>+	unsigned long flags;
>+	unsigned short ident = P_IDENT(per);
>+
>+	if (per & P_DONTCARE)
>+		return;
>+
>+	if (!(per & P_DEFINED))
>+		return;
>+
>+	if (check_gpio(ident) < 0)
>+		return;
>+
>+	local_irq_save(flags);
>+
>+	if (unlikely(!(reserved_peri_map[gpio_bank(ident)]
>+			 & gpio_bit(ident)))) {
>+		local_irq_restore(flags);
>+		return;
>+	}
>+
>+	if (!(per & P_MAYSHARE)) {
>+		port_setup(ident, GPIO_USAGE);
>+	}
>+
>+	reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
>+
>+	local_irq_restore(flags);
>+}
>+EXPORT_SYMBOL(peripheral_free);
>+
>+void peripheral_free_list(unsigned short per[])
>+{
>+	u16 cnt;
>+
>+	for (cnt = 0; per[cnt] != 0; cnt++) {
>+		peripheral_free(per[cnt]);
>+	}
>+
>+}
>+EXPORT_SYMBOL(peripheral_free_list);
>+
> /***********************************************************
> *
> * FUNCTIONS: Blackfin GPIO Driver
>@@ -574,13 +784,13 @@ int gpio_request(unsigned short gpio, const char
>*label)
>
> 	local_irq_save(flags);
>
>-	if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
>+	if (unlikely(reserved_gpio_map[gpio_bank(gpio)] &
gpio_bit(gpio))) {
> 		printk(KERN_ERR "bfin-gpio: GPIO %d is already
reserved!\n",
>gpio);
> 		dump_stack();
> 		local_irq_restore(flags);
> 		return -EBUSY;
> 	}
>-	reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
>+	reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
>
> 	local_irq_restore(flags);
>
>@@ -599,7 +809,7 @@ void gpio_free(unsigned short gpio)
>
> 	local_irq_save(flags);
>
>-	if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))))
{
>+	if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] &
gpio_bit(gpio))))
>{
> 		printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n",
gpio);
> 		dump_stack();
> 		local_irq_restore(flags);
>@@ -608,7 +818,7 @@ void gpio_free(unsigned short gpio)
>
> 	default_gpio(gpio);
>
>-	reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
>+	reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
>
> 	local_irq_restore(flags);
> }
>@@ -618,7 +828,7 @@ void gpio_direction_input(unsigned short gpio)
> {
> 	unsigned long flags;
>
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>
> 	local_irq_save(flags);
> 	gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
>@@ -631,7 +841,7 @@ void gpio_direction_output(unsigned short gpio)
> {
> 	unsigned long flags;
>
>-	BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
>
> 	local_irq_save(flags);
> 	gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
>diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
>b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
>index e043caf..69b9f8e 100644
>--- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
>+++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
>@@ -1,5 +1,6 @@
> #include <linux/serial.h>
> #include <asm/dma.h>
>+#include <asm/portmux.h>
>
> #define NR_PORTS                1
>
>@@ -92,18 +93,24 @@ struct bfin_serial_res bfin_serial_resource[] = {
> 	}
> };
>
>+#define DRIVER_NAME "bfin-uart"
>
> int nr_ports = NR_PORTS;
> static void bfin_serial_hw_init(struct bfin_serial_port *uart)
> {
>
>+#ifdef CONFIG_SERIAL_BFIN_UART0
>+	peripheral_request(P_UART0_TX, DRIVER_NAME);
>+	peripheral_request(P_UART0_RX, DRIVER_NAME);
>+#endif
>+
> #ifdef CONFIG_SERIAL_BFIN_CTSRTS
> 	if (uart->cts_pin >= 0) {
>-		gpio_request(uart->cts_pin, NULL);
>+		gpio_request(uart->cts_pin, DRIVER_NAME);
> 		gpio_direction_input(uart->cts_pin);
> 	}
> 	if (uart->rts_pin >= 0) {
>-		gpio_request(uart->rts_pin, NULL);
>+		gpio_request(uart->rts_pin, DRIVER_NAME);
> 		gpio_direction_input(uart->rts_pin);
> 	}
> #endif
>diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
>b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
>index 8f5d9c4..6fb328f 100644
>--- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
>+++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
>@@ -1,5 +1,6 @@
> #include <linux/serial.h>
> #include <asm/dma.h>
>+#include <asm/portmux.h>
>
> #define NR_PORTS		2
>
>@@ -122,25 +123,29 @@ struct bfin_serial_res bfin_serial_resource[] = {
>
> int nr_ports = ARRAY_SIZE(bfin_serial_resource);
>
>+#define DRIVER_NAME "bfin-uart"
>+
> static void bfin_serial_hw_init(struct bfin_serial_port *uart)
> {
>-	unsigned short val;
>-	val = bfin_read16(BFIN_PORT_MUX);
>-	val &= ~(PFDE | PFTE);
>-	bfin_write16(BFIN_PORT_MUX, val);
>
>-	val = bfin_read16(PORTF_FER);
>-	val |= 0xF;
>-	bfin_write16(PORTF_FER, val);
>+#ifdef CONFIG_SERIAL_BFIN_UART0
>+	peripheral_request(P_UART0_TX, DRIVER_NAME);
>+	peripheral_request(P_UART0_RX, DRIVER_NAME);
>+#endif
>+
>+#ifdef CONFIG_SERIAL_BFIN_UART1
>+	peripheral_request(P_UART1_TX, DRIVER_NAME);
>+	peripheral_request(P_UART1_RX, DRIVER_NAME);
>+#endif
>
> #ifdef CONFIG_SERIAL_BFIN_CTSRTS
> 	if (uart->cts_pin >= 0) {
>-		gpio_request(uart->cts_pin, NULL);
>+		gpio_request(uart->cts_pin, DRIVER_NAME);
> 		gpio_direction_input(uart->cts_pin);
> 	}
>
> 	if (uart->rts_pin >= 0) {
>-		gpio_request(uart->rts_pin, NULL);
>+		gpio_request(uart->rts_pin, DRIVER_NAME);
> 		gpio_direction_output(uart->rts_pin);
> 	}
> #endif
>diff --git a/include/asm-blackfin/mach-bf537/portmux.h b/include/asm-
>blackfin/mach-bf537/portmux.h
>index 23e13c5..7daa247 100644
>--- a/include/asm-blackfin/mach-bf537/portmux.h
>+++ b/include/asm-blackfin/mach-bf537/portmux.h
>@@ -106,4 +106,4 @@
> #define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
> #define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(2))
>
>-#endif /* _MACH_PORTMUX_H_ */
>+#endif				/* _MACH_PORTMUX_H_ */
>diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
>b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
>index e043caf..69b9f8e 100644
>--- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
>+++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
>@@ -1,5 +1,6 @@
> #include <linux/serial.h>
> #include <asm/dma.h>
>+#include <asm/portmux.h>
>
> #define NR_PORTS                1
>
>@@ -92,18 +93,24 @@ struct bfin_serial_res bfin_serial_resource[] = {
> 	}
> };
>
>+#define DRIVER_NAME "bfin-uart"
>
> int nr_ports = NR_PORTS;
> static void bfin_serial_hw_init(struct bfin_serial_port *uart)
> {
>
>+#ifdef CONFIG_SERIAL_BFIN_UART0
>+	peripheral_request(P_UART0_TX, DRIVER_NAME);
>+	peripheral_request(P_UART0_RX, DRIVER_NAME);
>+#endif
>+
> #ifdef CONFIG_SERIAL_BFIN_CTSRTS
> 	if (uart->cts_pin >= 0) {
>-		gpio_request(uart->cts_pin, NULL);
>+		gpio_request(uart->cts_pin, DRIVER_NAME);
> 		gpio_direction_input(uart->cts_pin);
> 	}
> 	if (uart->rts_pin >= 0) {
>-		gpio_request(uart->rts_pin, NULL);
>+		gpio_request(uart->rts_pin, DRIVER_NAME);
> 		gpio_direction_input(uart->rts_pin);
> 	}
> #endif
>--
>1.5.2

^ permalink raw reply	[flat|nested] 33+ messages in thread
* RE: [PATCH 01/12] Blackfin arch: add peripheral resource allocation support
@ 2007-08-17 20:02 Hennerich, Michael
  2007-08-17 21:10 ` David Brownell
  0 siblings, 1 reply; 33+ messages in thread
From: Hennerich, Michael @ 2007-08-17 20:02 UTC (permalink / raw)
  To: David Brownell, Bryan Wu; +Cc: torvalds, linux-kernel, akpm, Michael Hennerich

Hi Dave,

>-----Original Message-----
>From: David Brownell [mailto:david-b@pacbell.net]
>Sent: Freitag, 17. August 2007 20:12
>To: Bryan Wu
>Cc: torvalds@linux-foundation.org; linux-kernel@vger.kernel.org;
>akpm@linux-foundation.org; Michael Hennerich
>Subject: Re: [PATCH 01/12] Blackfin arch: add peripheral resource
>allocation support
>
>On Tuesday 07 August 2007, Bryan Wu wrote:
>> From: Michael Hennerich <michael.hennerich@analog.com>
>
>The patch description here is IMO misleading, and is clearly
>weak-to-nonexistent ...  what this patch does is
>
> * Start tracking the label strings provided by gpio_request()
> * Provide a new portmux mechanisms
> * Start using those in the serial support code
>

Right - our patch descriptions needs to be worked on.  


>When I read "resource allocation" I think of "struct resource"
>from <linux/ioport.h>, allocate_resource(), and so on.  So while
>it's true there are other kinds of driver resource, it's rather
>unnatural for me to think about pin mux and gpio issues in any
>terms other than chip and board setup.

Let me explain a bit. On some Blackfin derivatives almost all PINs can
be GPIOs besides up to 4 alternative functions. For a well experienced
systems engineer being the same time the same guy who does the Hardware
and the Software this is not an issue. 
We provide all kind of drivers utilizing almost any peripheral on
Blackfin. 
While potentially causing conflicting usage, for someone without
detailed hardware knowledge. The platform device board file is a good
thing to track conflicting memory or IO space resources as well as IRQs.
We also utilize platform device files for exactly these purposes.

The dynamic resource allocation for pinmux and gpio seems to us the best
way to handle things. The "resource allocation" mechanism will spill an
error and dump in case conflicting usage is detected. It'll also tell
you who is causing the conflicting usage.       

>
>
>> +static int cmp_label(unsigned short ident, const char *label)
>> +{
>> +	if (label && str_ident)
>> +		return strncmp(str_ident + ident * RESOURCE_LABEL_SIZE,
>> +				 label, strlen(label));
>> +	else
>> +		return -EINVAL;
>> +}
>
>GRPIO labels are purely for diagnostics.  There's no reason to
>compare one to another.  You seem to be using these for purposes
>in addition to GPIOs though ... probably worth commenting on that
>unusual scheme.

You are right - diagnostics:
Telling who claimed my resource.
In addition getting a signature, allowing double allocation.

Some drives provide the option for a simple callback function exported
though the platform device file, in order to toggle a GPIO powering up
some external device. Without some additional global external flag it's
pretty had to maintain whether this gpio was allocated before.
In this case I prefer to allow double allocation, for the same purpose. 
  

>
>
>> +int peripheral_request(unsigned short per, const char *label)
>> +{
>> +	...
>> +
>> +	if (unlikely(reserved_peri_map[gpio_bank(ident)] &
gpio_bit(ident)))
>{
>> +
>> +	/*
>> +	 * Pin functions like AMC address strobes my
>> +	 * be requested and used by several drivers
>> +	 */
>> +
>> +	if (!(per & P_MAYSHARE)) {
>
>Goofy indentation.  And as a rule, drivers have been kept out of
>the business of configuring pin usage.  It's simpler that way;
>they don't need to try coping with configuration errors like two
>drivers wanting conflicting usage ... or as you say above, needing
>some explicit sharing mechanism ...


We define some PINs or better single PIN functions to be may shared.
This is only for PINs where the sharing of the function is in nature.
Think about an address strobe or a bus (Busy/Wait) signal, used by
several
drivers/devices sharing the same bus.


>
>
>> +
>> +	/*
>> +	 * Allow that the identical pin function can
>> +	 * be requested from the same driver twice
>> +	 */
>
>... or as you say here, needing to structure themselves so they
>don't configure the same usage more than once ...


Same as explained above - this is only for these spots where the
request/free scheme doesn't work. 

>
>
>That said, how you handle pinmux on Blackfin is your business.
>
>But you should know that this approach seems idiosyncratic and
>more complex than needed:  when pin config is done early and as
>part of board setup, drivers don't need to care about it or to
>handle any pinmux errors.  And heck, products can sometimes be
>shipped with the bootloader having done all pinmux setup, so
>Linux won't need to worry about it at all.  That can help ship
>multiple board revisions using the same kernel.

This works for fixed function boards. But not for development boards
where we provide lego like add on cards, and allow people to connect
their homebrewn hardware.  

Most people/customers I cope with, use the boot loader to only boot the
Linux kernel. The hardware setup we default the processor in the boot
loader might not fit their applications needs.   

-Michael

>
>- Dave
>

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

end of thread, other threads:[~2007-08-20  3:42 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08  3:35 [PATCH 00/12] Blackfin arch GPIO updating Bryan Wu
2007-08-08  3:35 ` [PATCH 01/12] Blackfin arch: add peripheral resource allocation support Bryan Wu
2007-08-17 18:12   ` David Brownell
2007-08-08  3:35 ` [PATCH 02/12] Blackfin arch: Add label to call new GPIO API Bryan Wu
2007-08-17 18:24   ` David Brownell
2007-08-17 19:45     ` Mike Frysinger
2007-08-17 20:09       ` David Brownell
2007-08-17 20:19         ` Mike Frysinger
2007-08-17 20:21           ` Mike Frysinger
2007-08-17 21:15           ` David Brownell
2007-08-17 21:53     ` Robin Getz
2007-08-17 22:34       ` David Brownell
2007-08-18 19:07         ` Robin Getz
2007-08-19 21:54           ` David Brownell
2007-08-20  1:55             ` Robin Getz
2007-08-20  3:41               ` David Brownell
2007-08-08  3:35 ` [PATCH 03/12] Blackfin arch: fix PORT_J BUG for BF537/6 EMAC driver Bryan Wu
2007-08-08  3:35 ` [PATCH 04/12] Blackfin arch: Finalize the generic gpio support - add gpio_to_irq and irq_to_gpio Bryan Wu
2007-08-08  3:35 ` [PATCH 05/12] Blackfin arch: Advertise GENERIC_GPIO and remove duplicated GENERIC_CALIBRATE_DELAY Bryan Wu
2007-08-08  3:35 ` [PATCH 06/12] Blackfin arch: Add PORT_J.High (needed for BF548-EZkit Touchscreen interrupts) - remove PORT_C.H Bryan Wu
2007-08-08  3:35 ` [PATCH 07/12] Blackfin arch: bug fixing, add missing BF533_FAMILY GPIO_PFx definition Bryan Wu
2007-08-08  3:35 ` [PATCH 08/12] Blackfin arch: add missing gpio error handling to make sure we roll back requests in case one fails Bryan Wu
2007-08-08  3:35 ` [PATCH 09/12] Blackfin arch: scrub remaining ASSEMBLY usage since the switch to __ASSEMBLY__ Bryan Wu
2007-08-08  3:35 ` [PATCH 10/12] Blackfin arch: update platform driver resource information to the ezkitBF548 board file Bryan Wu
2007-08-08  3:35 ` [PATCH 11/12] Blackfin arch: after removing fs.h from mm.h, fix the broken on Blackfin arch Bryan Wu
2007-08-08  3:35 ` [PATCH 12/12] Blackfin serial driver: use new GPIO API Bryan Wu
2007-08-17 17:29   ` David Brownell
2007-08-08  7:18 [PATCH 01/12] Blackfin arch: add peripheral resource allocation support Hennerich, Michael
2007-08-08  7:49 ` Bryan Wu
2007-08-17 20:02 Hennerich, Michael
2007-08-17 21:10 ` David Brownell
2007-08-17 22:15   ` Robin Getz
2007-08-17 22:46     ` David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome