Skip to content
Snippets Groups Projects
Commit d92be314 authored by Bruce Ashfield's avatar Bruce Ashfield
Browse files

mfd: lpc_sch: Accomodate partial population of the MFD devices


1/4 [
Author: Darren Hart
Email: dvhart@linux.intel.com
Subject: mfd: lpc_sch: Accomodate partial population of the MFD devices
Date: Sat, 18 May 2013 14:45:52 -0700

commit 5829e9b64e657560e840dc0ecfee177cb002cd69 upstream

The current probe aborts if any of the 3 base address registers are
disabled. On a TunnelCreek system I am working on, this resulted in the
SMBIOS and GPIO devices being removed when it couldn't read the base
address for the watchdog timer.

This patch accommodates partial population of the lpc_sch_cells array and
only aborts if all the base address registers are disabled. A max size
array is allocated and the individual device cells are added to it after
their base addresses are successfully determined. This simplifies the
code a bit by removing the need for the separate tunnelcreek cells array
and combining some of the add/remove logic.

Cc: Grant Likely <grant.likely@secretlab.ca>,
Cc: Denis Turischev <denis@compulab.co.il>,
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarDarren Hart <dvhart@linux.intel.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
]

2/4 [
Author: Darren Hart
Email: dvhart@linux.intel.com
Subject: gpio-sch: Allow for more than 8 lines in the resume well
Date: Sat, 18 May 2013 14:45:53 -0700

commit 3cbf1822b5fd98eccb641c94c8cd2455fdad9221 upstream

The E6xx (TunnelCreek) CPUs have 9 GPIO lines in the resume well. Update
the resume functions to allow for more than 8 GPIO lines, using the core
functions as a template.

Cc: <stable@vger.kernel.org> # 3.4.x
Cc: <stable@vger.kernel.org> # 3.8.x
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarDarren Hart <dvhart@linux.intel.com>
]

3/4 [
Author: Darren Hart
Email: dvhart@linux.intel.com
Subject: pch_gbe: Use PCH_GBE_PHY_REGS_LEN instead of 32
Date: Sat, 18 May 2013 14:45:55 -0700

Avoid using magic numbers when we have perfectly good defines just lying
around.

Signed-off-by: default avatarDarren Hart <dvhart@linux.intel.com>
]

4/4 [
Author: Darren Hart
Email: darren@dvhart.com
Subject: pch_uart: Add uart_clk selection for the MinnowBoard
Date: Sat, 18 May 2013 14:45:56 -0700

Use DMI_BOARD_NAME to determine if we are running on a MinnowBoard and
set the uart clock to 50MHz if so. This removes the need to pass the
user_uartclk to the kernel at boot time.

Signed-off-by: default avatarDarren Hart <dvhart@linux.intel.com>
]

Signed-off-by: default avatarBruce Ashfield <bruce.ashfield@windriver.com>
parent a4481a40
No related branches found
No related tags found
No related merge requests found
# merged upstream
#patch MIPS-i8259-Use-struct-syscore_ops-instead-of-sysdevs.patch
patch mfd-lpc_sch-Accomodate-partial-population-of-the-MFD.patch
patch gpio-sch-Allow-for-more-than-8-lines-in-the-resume-w.patch
patch pch_gbe-Use-PCH_GBE_PHY_REGS_LEN-instead-of-32.patch
patch pch_uart-Add-uart_clk-selection-for-the-MinnowBoard.patch
From 0daa5c8eed91b6ea670f679644b43be0f53e80ed Mon Sep 17 00:00:00 2001
From: Darren Hart <dvhart@linux.intel.com>
Date: Sat, 18 May 2013 14:45:53 -0700
Subject: [PATCH 2/4] gpio-sch: Allow for more than 8 lines in the resume well
commit 3cbf1822b5fd98eccb641c94c8cd2455fdad9221 upstream
The E6xx (TunnelCreek) CPUs have 9 GPIO lines in the resume well. Update
the resume functions to allow for more than 8 GPIO lines, using the core
functions as a template.
Cc: <stable@vger.kernel.org> # 3.4.x
Cc: <stable@vger.kernel.org> # 3.8.x
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
drivers/gpio/gpio-sch.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index edae963..529c488 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -125,13 +125,17 @@ static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
unsigned gpio_num)
{
u8 curr_dirs;
+ unsigned short offset, bit;
spin_lock(&gpio_lock);
- curr_dirs = inb(gpio_ba + RGIO);
+ offset = RGIO + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ curr_dirs = inb(gpio_ba + offset);
- if (!(curr_dirs & (1 << gpio_num)))
- outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO);
+ if (!(curr_dirs & (1 << bit)))
+ outb(curr_dirs | (1 << bit) , gpio_ba + offset);
spin_unlock(&gpio_lock);
return 0;
@@ -139,22 +143,31 @@ static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
{
- return !!(inb(gpio_ba + RGLV) & (1 << gpio_num));
+ unsigned short offset, bit;
+
+ offset = RGLV + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ return !!(inb(gpio_ba + offset) & (1 << bit));
}
static void sch_gpio_resume_set(struct gpio_chip *gc,
unsigned gpio_num, int val)
{
u8 curr_vals;
+ unsigned short offset, bit;
spin_lock(&gpio_lock);
- curr_vals = inb(gpio_ba + RGLV);
+ offset = RGLV + gpio_num / 8;
+ bit = gpio_num % 8;
+
+ curr_vals = inb(gpio_ba + offset);
if (val)
- outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV);
+ outb(curr_vals | (1 << bit), gpio_ba + offset);
else
- outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV);
+ outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
spin_unlock(&gpio_lock);
}
@@ -163,14 +176,18 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
unsigned gpio_num, int val)
{
u8 curr_dirs;
+ unsigned short offset, bit;
sch_gpio_resume_set(gc, gpio_num, val);
+ offset = RGIO + gpio_num / 8;
+ bit = gpio_num % 8;
+
spin_lock(&gpio_lock);
- curr_dirs = inb(gpio_ba + RGIO);
- if (curr_dirs & (1 << gpio_num))
- outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO);
+ curr_dirs = inb(gpio_ba + offset);
+ if (curr_dirs & (1 << bit))
+ outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock);
return 0;
--
1.7.10.4
From 64bf5aebc72faecb87baea47caae195fdca44d4a Mon Sep 17 00:00:00 2001
From: Darren Hart <dvhart@linux.intel.com>
Date: Sat, 18 May 2013 14:45:52 -0700
Subject: [PATCH 1/4] mfd: lpc_sch: Accomodate partial population of the MFD
devices
commit 5829e9b64e657560e840dc0ecfee177cb002cd69 upstream
The current probe aborts if any of the 3 base address registers are
disabled. On a TunnelCreek system I am working on, this resulted in the
SMBIOS and GPIO devices being removed when it couldn't read the base
address for the watchdog timer.
This patch accommodates partial population of the lpc_sch_cells array and
only aborts if all the base address registers are disabled. A max size
array is allocated and the individual device cells are added to it after
their base addresses are successfully determined. This simplifies the
code a bit by removing the need for the separate tunnelcreek cells array
and combining some of the add/remove logic.
Cc: Grant Likely <grant.likely@secretlab.ca>,
Cc: Denis Turischev <denis@compulab.co.il>,
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
drivers/mfd/lpc_sch.c | 147 ++++++++++++++++++++++++-------------------------
1 file changed, 71 insertions(+), 76 deletions(-)
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index 5624fcb..8cc6aac 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -45,34 +45,32 @@ static struct resource smbus_sch_resource = {
.flags = IORESOURCE_IO,
};
-
static struct resource gpio_sch_resource = {
.flags = IORESOURCE_IO,
};
-static struct mfd_cell lpc_sch_cells[] = {
- {
- .name = "isch_smbus",
- .num_resources = 1,
- .resources = &smbus_sch_resource,
- },
- {
- .name = "sch_gpio",
- .num_resources = 1,
- .resources = &gpio_sch_resource,
- },
-};
-
static struct resource wdt_sch_resource = {
.flags = IORESOURCE_IO,
};
-static struct mfd_cell tunnelcreek_cells[] = {
- {
- .name = "ie6xx_wdt",
- .num_resources = 1,
- .resources = &wdt_sch_resource,
- },
+static struct mfd_cell lpc_sch_cells[3];
+
+static struct mfd_cell isch_smbus_cell = {
+ .name = "isch_smbus",
+ .num_resources = 1,
+ .resources = &smbus_sch_resource,
+};
+
+static struct mfd_cell sch_gpio_cell = {
+ .name = "sch_gpio",
+ .num_resources = 1,
+ .resources = &gpio_sch_resource,
+};
+
+static struct mfd_cell wdt_sch_cell = {
+ .name = "ie6xx_wdt",
+ .num_resources = 1,
+ .resources = &wdt_sch_resource,
};
static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
@@ -88,79 +86,76 @@ static int lpc_sch_probe(struct pci_dev *dev,
{
unsigned int base_addr_cfg;
unsigned short base_addr;
- int i;
+ int i, cells = 0;
int ret;
pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
- if (!(base_addr_cfg & (1 << 31))) {
- dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n");
- return -ENODEV;
- }
- base_addr = (unsigned short)base_addr_cfg;
- if (base_addr == 0) {
- dev_err(&dev->dev, "I/O space for SMBus uninitialized\n");
- return -ENODEV;
- }
-
- smbus_sch_resource.start = base_addr;
- smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1;
+ base_addr = 0;
+ if (!(base_addr_cfg & (1 << 31)))
+ dev_warn(&dev->dev, "Decode of the SMBus I/O range disabled\n");
+ else
+ base_addr = (unsigned short)base_addr_cfg;
- pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
- if (!(base_addr_cfg & (1 << 31))) {
- dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n");
- return -ENODEV;
- }
- base_addr = (unsigned short)base_addr_cfg;
if (base_addr == 0) {
- dev_err(&dev->dev, "I/O space for GPIO uninitialized\n");
- return -ENODEV;
+ dev_warn(&dev->dev, "I/O space for SMBus uninitialized\n");
+ } else {
+ lpc_sch_cells[cells++] = isch_smbus_cell;
+ smbus_sch_resource.start = base_addr;
+ smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1;
}
- gpio_sch_resource.start = base_addr;
-
- if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB)
- gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1;
+ pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
+ base_addr = 0;
+ if (!(base_addr_cfg & (1 << 31)))
+ dev_warn(&dev->dev, "Decode of the GPIO I/O range disabled\n");
else
- gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
-
- for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++)
- lpc_sch_cells[i].id = id->device;
+ base_addr = (unsigned short)base_addr_cfg;
- ret = mfd_add_devices(&dev->dev, 0,
- lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL,
- 0, NULL);
- if (ret)
- goto out_dev;
+ if (base_addr == 0) {
+ dev_warn(&dev->dev, "I/O space for GPIO uninitialized\n");
+ } else {
+ lpc_sch_cells[cells++] = sch_gpio_cell;
+ gpio_sch_resource.start = base_addr;
+ if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB)
+ gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1;
+ else
+ gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
+ }
if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC
- || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) {
+ || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) {
pci_read_config_dword(dev, WDTBASE, &base_addr_cfg);
- if (!(base_addr_cfg & (1 << 31))) {
- dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n");
- ret = -ENODEV;
- goto out_dev;
+ base_addr = 0;
+ if (!(base_addr_cfg & (1 << 31)))
+ dev_warn(&dev->dev, "Decode of the WDT I/O range disabled\n");
+ else
+ base_addr = (unsigned short)base_addr_cfg;
+ if (base_addr == 0)
+ dev_warn(&dev->dev, "I/O space for WDT uninitialized\n");
+ else {
+ lpc_sch_cells[cells++] = wdt_sch_cell;
+ wdt_sch_resource.start = base_addr;
+ wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1;
}
- base_addr = (unsigned short)base_addr_cfg;
- if (base_addr == 0) {
- dev_err(&dev->dev, "I/O space for WDT uninitialized\n");
- ret = -ENODEV;
- goto out_dev;
- }
-
- wdt_sch_resource.start = base_addr;
- wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1;
+ }
- for (i = 0; i < ARRAY_SIZE(tunnelcreek_cells); i++)
- tunnelcreek_cells[i].id = id->device;
+ if (WARN_ON(cells > ARRAY_SIZE(lpc_sch_cells))) {
+ dev_err(&dev->dev, "Cell count exceeds array size");
+ return -ENODEV;
+ }
- ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells,
- ARRAY_SIZE(tunnelcreek_cells), NULL,
- 0, NULL);
+ if (cells == 0) {
+ dev_err(&dev->dev, "All decode registers disabled.\n");
+ return -ENODEV;
}
- return ret;
-out_dev:
- mfd_remove_devices(&dev->dev);
+ for (i = 0; i < cells; i++)
+ lpc_sch_cells[i].id = id->device;
+
+ ret = mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL);
+ if (ret)
+ mfd_remove_devices(&dev->dev);
+
return ret;
}
--
1.7.10.4
From e844306965048d528c14a725cf2fd9c8a8e17406 Mon Sep 17 00:00:00 2001
From: Darren Hart <dvhart@linux.intel.com>
Date: Sat, 18 May 2013 14:45:55 -0700
Subject: [PATCH 3/4] pch_gbe: Use PCH_GBE_PHY_REGS_LEN instead of 32
Avoid using magic numbers when we have perfectly good defines just lying
around.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 73ce7dd..8adeb4d 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -670,7 +670,7 @@ static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter)
}
adapter->hw.phy.addr = adapter->mii.phy_id;
pr_debug("phy_addr = %d\n", adapter->mii.phy_id);
- if (addr == 32)
+ if (addr == PCH_GBE_PHY_REGS_LEN)
return -EAGAIN;
/* Selected the phy and isolate the rest */
for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) {
--
1.7.10.4
From 6ed6ca790b7afef5881de4566850bbc30ae26df6 Mon Sep 17 00:00:00 2001
From: Darren Hart <darren@dvhart.com>
Date: Sat, 18 May 2013 14:45:56 -0700
Subject: [PATCH 4/4] pch_uart: Add uart_clk selection for the MinnowBoard
Use DMI_BOARD_NAME to determine if we are running on a MinnowBoard and
set the uart clock to 50MHz if so. This removes the need to pass the
user_uartclk to the kernel at boot time.
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
drivers/tty/serial/pch_uart.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 8318925..a9e4be7 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -214,6 +214,7 @@ enum {
#define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */
#define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */
#define NTC1_UARTCLK 64000000 /* 64.0000 MHz */
+#define MINNOW_UARTCLK 50000000 /* 50.0000 MHz */
struct pch_uart_buffer {
unsigned char *buf;
@@ -395,6 +396,10 @@ static int pch_uart_get_uartclk(void)
strstr(cmp, "nanoETXexpress-TT")))
return NTC1_UARTCLK;
+ cmp = dmi_get_system_info(DMI_BOARD_NAME);
+ if (cmp && strstr(cmp, "MinnowBoard"))
+ return MINNOW_UARTCLK;
+
return DEFAULT_UARTCLK;
}
--
1.7.10.4
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment