summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 00:25:35 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 00:25:35 +0400
commitd2033f2c1d1de2239ded15e478ddb4028f192a15 (patch)
treed60e4f447134ca008ef212c04f0e75256681ed04 /drivers
parent22237d5a588cfad92525d2998ff14d3666399dce (diff)
parent0ee8090c1d059eca4d60e8e473bee91fb5d1996b (diff)
downloadlinux-d2033f2c1d1de2239ded15e478ddb4028f192a15.tar.xz
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Arnd Bergmann: "This contains cleanups as preparation for other branches adding new features, we pulled 16 branches for 9 platforms into this one. Most notable here is the removal of support for ATAGS based OMAP4 systems. Since all OMAP4 machines are fully functional with DT based booting in 3.10, we can remove a lot of code here. Also noteworthy is Maxime Ripard's cleanup of the machine descriptors, which means we need no machine descriptors in a lot more cases and can boot additional machines by just having the respective device drivers enabled." * tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (76 commits) ARM: picoxcell: remove .nr_irqs reference ARM: s5p64x0: avoid build warning for uncompress.h ARM: SAMSUNG: Remove unused plat/regs-watchdog.h header ARM: SAMSUNG: Remove legacy watchdog reset code ARM: SAMSUNG: Let platforms use the new watchdog reset driver ARM: SAMSUNG: Add watchdog reset driver ARM: SAMSUNG: Use local definitions of watchdog registers watchdog: s3c2410_wdt: Use local register definitions ARM: S5P64X0: Use common uncompress.h part for plat-samsung ARM: SAMSUNG: Consolidate uncompress subroutine ARM: at91: drop rm9200dk board support ARM: dts: msm: Fix merge resolution ARM: OMAP1: Remove dma.h ARM: OMAP1: Remove legacy irda.h and irda setup from board files ARM: OMAP1: Remove duplicated DMA channel definitions ARM: OMAP1: Remove McBSP DMA channel definitions ARM: OMAP2+: Remove dma.h ARM: OMAP2+: hwmod: Remove remaining DMA channel definitions ARM: OMAP2+: Remove duplicated DMA channel definitions ARM: OMAP2+: Remove AES crypto device DMA channel definitions ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bus/mvebu-mbus.c8
-rw-r--r--drivers/bus/omap-ocp2scp.c60
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/gpio-msm-v2.c195
-rw-r--r--drivers/of/address.c67
-rw-r--r--drivers/of/of_pci.c59
-rw-r--r--drivers/ssbi/ssbi.c69
-rw-r--r--drivers/watchdog/s3c2410_wdt.c17
8 files changed, 266 insertions, 211 deletions
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index 8740f46b4d0d..33c6947eebec 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -49,6 +49,8 @@
* configuration (file 'devices').
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -762,7 +764,7 @@ int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
break;
if (!s->soc->map[i].name) {
- pr_err("mvebu-mbus: unknown device '%s'\n", devname);
+ pr_err("unknown device '%s'\n", devname);
return -ENODEV;
}
@@ -775,7 +777,7 @@ int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
attr |= 0x28;
if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
- pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
+ pr_err("cannot add window '%s', conflicts with another window\n",
devname);
return -EINVAL;
}
@@ -842,7 +844,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
break;
if (!of_id->compatible) {
- pr_err("mvebu-mbus: could not find a matching SoC family\n");
+ pr_err("could not find a matching SoC family\n");
return -ENODEV;
}
diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c
index fe7191663bbd..5511f9814ddd 100644
--- a/drivers/bus/omap-ocp2scp.c
+++ b/drivers/bus/omap-ocp2scp.c
@@ -22,26 +22,6 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/platform_data/omap_ocp2scp.h>
-
-/**
- * _count_resources - count for the number of resources
- * @res: struct resource *
- *
- * Count and return the number of resources populated for the device that is
- * connected to ocp2scp.
- */
-static unsigned _count_resources(struct resource *res)
-{
- int cnt = 0;
-
- while (res->start != res->end) {
- cnt++;
- res++;
- }
-
- return cnt;
-}
static int ocp2scp_remove_devices(struct device *dev, void *c)
{
@@ -55,11 +35,7 @@ static int ocp2scp_remove_devices(struct device *dev, void *c)
static int omap_ocp2scp_probe(struct platform_device *pdev)
{
int ret;
- unsigned res_cnt, i;
struct device_node *np = pdev->dev.of_node;
- struct platform_device *pdev_child;
- struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
- struct omap_ocp2scp_dev *dev;
if (np) {
ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
@@ -68,48 +44,12 @@ static int omap_ocp2scp_probe(struct platform_device *pdev)
"failed to add resources for ocp2scp child\n");
goto err0;
}
- } else if (pdata) {
- for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
- dev++) {
- res_cnt = _count_resources(dev->res);
-
- pdev_child = platform_device_alloc(dev->drv_name,
- PLATFORM_DEVID_AUTO);
- if (!pdev_child) {
- dev_err(&pdev->dev,
- "failed to allocate mem for ocp2scp child\n");
- goto err0;
- }
-
- ret = platform_device_add_resources(pdev_child,
- dev->res, res_cnt);
- if (ret) {
- dev_err(&pdev->dev,
- "failed to add resources for ocp2scp child\n");
- goto err1;
- }
-
- pdev_child->dev.parent = &pdev->dev;
-
- ret = platform_device_add(pdev_child);
- if (ret) {
- dev_err(&pdev->dev,
- "failed to register ocp2scp child device\n");
- goto err1;
- }
- }
- } else {
- dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
- return -EINVAL;
}
pm_runtime_enable(&pdev->dev);
return 0;
-err1:
- platform_device_put(pdev_child);
-
err0:
device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 573c449c49b9..847a6dc15a54 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -165,7 +165,7 @@ config GPIO_MSM_V1
config GPIO_MSM_V2
tristate "Qualcomm MSM GPIO v2"
- depends on GPIOLIB && ARCH_MSM
+ depends on GPIOLIB && OF && ARCH_MSM
help
Say yes here to support the GPIO interface on ARM v7 based
Qualcomm MSM chips. Most of the pins on the MSM can be
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
index dd2eddeb1e0c..f4491a497cc8 100644
--- a/drivers/gpio/gpio-msm-v2.c
+++ b/drivers/gpio/gpio-msm-v2.c
@@ -19,18 +19,21 @@
#include <linux/bitmap.h>
#include <linux/bitops.h>
+#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/module.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
+#include <linux/slab.h>
-#include <mach/msm_gpiomux.h>
-#include <mach/msm_iomap.h>
+#define MAX_NR_GPIO 300
/* Bits of interest in the GPIO_IN_OUT register.
*/
@@ -77,13 +80,6 @@ enum {
TARGET_PROC_NONE = 7,
};
-
-#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
-#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
-#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
-#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
-#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
-
/**
* struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
*
@@ -102,11 +98,27 @@ enum {
*/
struct msm_gpio_dev {
struct gpio_chip gpio_chip;
- DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
- DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
- DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
+ DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+ DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
+ DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
+ struct irq_domain *domain;
+ unsigned int summary_irq;
+ void __iomem *msm_tlmm_base;
};
+struct msm_gpio_dev msm_gpio;
+
+#define GPIO_INTR_CFG_SU(gpio) (msm_gpio.msm_tlmm_base + 0x0400 + \
+ (0x04 * (gpio)))
+#define GPIO_CONFIG(gpio) (msm_gpio.msm_tlmm_base + 0x1000 + \
+ (0x10 * (gpio)))
+#define GPIO_IN_OUT(gpio) (msm_gpio.msm_tlmm_base + 0x1004 + \
+ (0x10 * (gpio)))
+#define GPIO_INTR_CFG(gpio) (msm_gpio.msm_tlmm_base + 0x1008 + \
+ (0x10 * (gpio)))
+#define GPIO_INTR_STATUS(gpio) (msm_gpio.msm_tlmm_base + 0x100c + \
+ (0x10 * (gpio)))
+
static DEFINE_SPINLOCK(tlmm_lock);
static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
@@ -159,37 +171,29 @@ static int msm_gpio_direction_output(struct gpio_chip *chip,
static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
{
- return msm_gpiomux_get(chip->base + offset);
+ return 0;
}
static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
{
- msm_gpiomux_put(chip->base + offset);
+ return;
}
static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return MSM_GPIO_TO_INT(chip->base + offset);
+ struct msm_gpio_dev *g_dev = to_msm_gpio_dev(chip);
+ struct irq_domain *domain = g_dev->domain;
+
+ return irq_create_mapping(domain, offset);
}
static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
{
- return irq - MSM_GPIO_TO_INT(chip->base);
+ struct irq_data *irq_data = irq_get_irq_data(irq);
+
+ return irq_data->hwirq;
}
-static struct msm_gpio_dev msm_gpio = {
- .gpio_chip = {
- .base = 0,
- .ngpio = NR_GPIO_IRQS,
- .direction_input = msm_gpio_direction_input,
- .direction_output = msm_gpio_direction_output,
- .get = msm_gpio_get,
- .set = msm_gpio_set,
- .to_irq = msm_gpio_to_irq,
- .request = msm_gpio_request,
- .free = msm_gpio_free,
- },
-};
/* For dual-edge interrupts in software, since the hardware has no
* such support:
@@ -227,9 +231,9 @@ static void msm_gpio_update_dual_edge_pos(unsigned gpio)
if (intstat || val == val2)
return;
} while (loop_limit-- > 0);
- pr_err("dual-edge irq failed to stabilize, "
+ pr_err("%s: dual-edge irq failed to stabilize, "
"interrupts dropped. %#08x != %#08x\n",
- val, val2);
+ __func__, val, val2);
}
static void msm_gpio_irq_ack(struct irq_data *d)
@@ -316,10 +320,10 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
- for_each_set_bit(i, msm_gpio.enabled_irqs, NR_GPIO_IRQS) {
+ for_each_set_bit(i, msm_gpio.enabled_irqs, MAX_NR_GPIO) {
if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
- generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
- i));
+ generic_handle_irq(irq_find_mapping(msm_gpio.domain,
+ i));
}
chained_irq_exit(chip, desc);
@@ -330,13 +334,13 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
if (on) {
- if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
- irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+ if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+ irq_set_irq_wake(msm_gpio.summary_irq, 1);
set_bit(gpio, msm_gpio.wake_irqs);
} else {
clear_bit(gpio, msm_gpio.wake_irqs);
- if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
- irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+ if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+ irq_set_irq_wake(msm_gpio.summary_irq, 0);
}
return 0;
@@ -351,30 +355,86 @@ static struct irq_chip msm_gpio_irq_chip = {
.irq_set_wake = msm_gpio_irq_set_wake,
};
-static int msm_gpio_probe(struct platform_device *dev)
+static struct lock_class_key msm_gpio_lock_class;
+
+static int msm_gpio_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
{
- int i, irq, ret;
+ irq_set_lockdep_class(irq, &msm_gpio_lock_class);
+ irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+
+ return 0;
+}
+
+static const struct irq_domain_ops msm_gpio_irq_domain_ops = {
+ .xlate = irq_domain_xlate_twocell,
+ .map = msm_gpio_irq_domain_map,
+};
+
+static int msm_gpio_probe(struct platform_device *pdev)
+{
+ int ret, ngpio;
+ struct resource *res;
+
+ if (!of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio)) {
+ dev_err(&pdev->dev, "%s: ngpio property missing\n", __func__);
+ return -EINVAL;
+ }
+
+ if (ngpio > MAX_NR_GPIO)
+ WARN(1, "ngpio exceeds the MAX_NR_GPIO. Increase MAX_NR_GPIO\n");
+
+ bitmap_zero(msm_gpio.enabled_irqs, MAX_NR_GPIO);
+ bitmap_zero(msm_gpio.wake_irqs, MAX_NR_GPIO);
+ bitmap_zero(msm_gpio.dual_edge_irqs, MAX_NR_GPIO);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ msm_gpio.msm_tlmm_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(msm_gpio.msm_tlmm_base))
+ return PTR_ERR(msm_gpio.msm_tlmm_base);
+
+ msm_gpio.gpio_chip.ngpio = ngpio;
+ msm_gpio.gpio_chip.label = pdev->name;
+ msm_gpio.gpio_chip.dev = &pdev->dev;
+ msm_gpio.gpio_chip.base = 0;
+ msm_gpio.gpio_chip.direction_input = msm_gpio_direction_input;
+ msm_gpio.gpio_chip.direction_output = msm_gpio_direction_output;
+ msm_gpio.gpio_chip.get = msm_gpio_get;
+ msm_gpio.gpio_chip.set = msm_gpio_set;
+ msm_gpio.gpio_chip.to_irq = msm_gpio_to_irq;
+ msm_gpio.gpio_chip.request = msm_gpio_request;
+ msm_gpio.gpio_chip.free = msm_gpio_free;
- bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
- bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
- bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
- msm_gpio.gpio_chip.label = dev->name;
ret = gpiochip_add(&msm_gpio.gpio_chip);
- if (ret < 0)
+ if (ret < 0) {
+ dev_err(&pdev->dev, "gpiochip_add failed with error %d\n", ret);
return ret;
+ }
- for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
- irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
- irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
- handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
+ msm_gpio.summary_irq = platform_get_irq(pdev, 0);
+ if (msm_gpio.summary_irq < 0) {
+ dev_err(&pdev->dev, "No Summary irq defined for msmgpio\n");
+ return msm_gpio.summary_irq;
}
- irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
- msm_summary_irq_handler);
+ msm_gpio.domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
+ &msm_gpio_irq_domain_ops,
+ &msm_gpio);
+ if (!msm_gpio.domain)
+ return -ENODEV;
+
+ irq_set_chained_handler(msm_gpio.summary_irq, msm_summary_irq_handler);
+
return 0;
}
+static struct of_device_id msm_gpio_of_match[] = {
+ { .compatible = "qcom,msm-gpio", },
+ { },
+};
+
static int msm_gpio_remove(struct platform_device *dev)
{
int ret = gpiochip_remove(&msm_gpio.gpio_chip);
@@ -382,7 +442,7 @@ static int msm_gpio_remove(struct platform_device *dev)
if (ret < 0)
return ret;
- irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+ irq_set_handler(msm_gpio.summary_irq, NULL);
return 0;
}
@@ -393,36 +453,11 @@ static struct platform_driver msm_gpio_driver = {
.driver = {
.name = "msmgpio",
.owner = THIS_MODULE,
+ .of_match_table = msm_gpio_of_match,
},
};
-static struct platform_device msm_device_gpio = {
- .name = "msmgpio",
- .id = -1,
-};
-
-static int __init msm_gpio_init(void)
-{
- int rc;
-
- rc = platform_driver_register(&msm_gpio_driver);
- if (!rc) {
- rc = platform_device_register(&msm_device_gpio);
- if (rc)
- platform_driver_unregister(&msm_gpio_driver);
- }
-
- return rc;
-}
-
-static void __exit msm_gpio_exit(void)
-{
- platform_device_unregister(&msm_device_gpio);
- platform_driver_unregister(&msm_gpio_driver);
-}
-
-postcore_initcall(msm_gpio_init);
-module_exit(msm_gpio_exit);
+module_platform_driver(msm_gpio_driver)
MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 04da786c84d2..fdd0636a987d 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -227,6 +227,73 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
}
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ const int na = 3, ns = 2;
+ int rlen;
+
+ parser->node = node;
+ parser->pna = of_n_addr_cells(node);
+ parser->np = parser->pna + na + ns;
+
+ parser->range = of_get_property(node, "ranges", &rlen);
+ if (parser->range == NULL)
+ return -ENOENT;
+
+ parser->end = parser->range + rlen / sizeof(__be32);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ const int na = 3, ns = 2;
+
+ if (!range)
+ return NULL;
+
+ if (!parser->range || parser->range + parser->np > parser->end)
+ return NULL;
+
+ range->pci_space = parser->range[0];
+ range->flags = of_bus_pci_get_flags(parser->range);
+ range->pci_addr = of_read_number(parser->range + 1, ns);
+ range->cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+ parser->range += parser->np;
+
+ /* Now consume following elements while they are contiguous */
+ while (parser->range + parser->np <= parser->end) {
+ u32 flags, pci_space;
+ u64 pci_addr, cpu_addr, size;
+
+ pci_space = be32_to_cpup(parser->range);
+ flags = of_bus_pci_get_flags(parser->range);
+ pci_addr = of_read_number(parser->range + 1, ns);
+ cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ size = of_read_number(parser->range + parser->pna + na, ns);
+
+ if (flags != range->flags)
+ break;
+ if (pci_addr != range->pci_addr + range->size ||
+ cpu_addr != range->cpu_addr + range->size)
+ break;
+
+ range->size += size;
+ parser->range += parser->np;
+ }
+
+ return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+
#endif /* CONFIG_PCI */
/*
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 13e37e2d8ec1..42c687a820ac 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -5,14 +5,15 @@
#include <asm/prom.h>
static inline int __of_pci_pci_compare(struct device_node *node,
- unsigned int devfn)
+ unsigned int data)
{
- unsigned int size;
- const __be32 *reg = of_get_property(node, "reg", &size);
+ int devfn;
- if (!reg || size < 5 * sizeof(__be32))
+ devfn = of_pci_get_devfn(node);
+ if (devfn < 0)
return 0;
- return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn;
+
+ return devfn == data;
}
struct device_node *of_pci_find_child_device(struct device_node *parent,
@@ -40,3 +41,51 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
return NULL;
}
EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+ unsigned int size;
+ const __be32 *reg;
+
+ reg = of_get_property(np, "reg", &size);
+
+ if (!reg || size < 5 * sizeof(__be32))
+ return -EINVAL;
+
+ return (be32_to_cpup(reg) >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+ const __be32 *values;
+ int len;
+
+ values = of_get_property(node, "bus-range", &len);
+ if (!values || len < sizeof(*values) * 2)
+ return -EINVAL;
+
+ res->name = node->name;
+ res->start = be32_to_cpup(values++);
+ res->end = be32_to_cpup(values);
+ res->flags = IORESOURCE_BUS;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
diff --git a/drivers/ssbi/ssbi.c b/drivers/ssbi/ssbi.c
index e561d3be54a5..102a22844297 100644
--- a/drivers/ssbi/ssbi.c
+++ b/drivers/ssbi/ssbi.c
@@ -268,35 +268,23 @@ static int ssbi_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct resource *mem_res;
struct ssbi *ssbi;
- int ret = 0;
const char *type;
- ssbi = kzalloc(sizeof(struct ssbi), GFP_KERNEL);
- if (!ssbi) {
- pr_err("can not allocate ssbi_data\n");
+ ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
+ if (!ssbi)
return -ENOMEM;
- }
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem_res) {
- pr_err("missing mem resource\n");
- ret = -EINVAL;
- goto err_get_mem_res;
- }
+ ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
+ if (IS_ERR(ssbi->base))
+ return PTR_ERR(ssbi->base);
- ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
- if (!ssbi->base) {
- pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
- ret = -EINVAL;
- goto err_ioremap;
- }
platform_set_drvdata(pdev, ssbi);
type = of_get_property(np, "qcom,controller-type", NULL);
if (type == NULL) {
- pr_err("Missing qcom,controller-type property\n");
- ret = -EINVAL;
- goto err_ssbi_controller;
+ dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
+ return -EINVAL;
}
dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
if (strcmp(type, "ssbi") == 0)
@@ -306,9 +294,8 @@ static int ssbi_probe(struct platform_device *pdev)
else if (strcmp(type, "pmic-arbiter") == 0)
ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
else {
- pr_err("Unknown qcom,controller-type\n");
- ret = -EINVAL;
- goto err_ssbi_controller;
+ dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
+ return -EINVAL;
}
if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
@@ -321,29 +308,7 @@ static int ssbi_probe(struct platform_device *pdev)
spin_lock_init(&ssbi->lock);
- ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
- if (ret)
- goto err_ssbi_controller;
-
- return 0;
-
-err_ssbi_controller:
- platform_set_drvdata(pdev, NULL);
- iounmap(ssbi->base);
-err_ioremap:
-err_get_mem_res:
- kfree(ssbi);
- return ret;
-}
-
-static int ssbi_remove(struct platform_device *pdev)
-{
- struct ssbi *ssbi = platform_get_drvdata(pdev);
-
- platform_set_drvdata(pdev, NULL);
- iounmap(ssbi->base);
- kfree(ssbi);
- return 0;
+ return of_platform_populate(np, NULL, NULL, &pdev->dev);
}
static struct of_device_id ssbi_match_table[] = {
@@ -354,25 +319,13 @@ MODULE_DEVICE_TABLE(of, ssbi_match_table);
static struct platform_driver ssbi_driver = {
.probe = ssbi_probe,
- .remove = ssbi_remove,
.driver = {
.name = "ssbi",
.owner = THIS_MODULE,
.of_match_table = ssbi_match_table,
},
};
-
-static int __init ssbi_init(void)
-{
- return platform_driver_register(&ssbi_driver);
-}
-module_init(ssbi_init);
-
-static void __exit ssbi_exit(void)
-{
- platform_driver_unregister(&ssbi_driver);
-}
-module_exit(ssbi_exit)
+module_platform_driver(ssbi_driver);
MODULE_LICENSE("GPL v2");
MODULE_VERSION("1.0");
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index ee03135f5abd..3a9f6961db2d 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -42,12 +42,21 @@
#include <linux/err.h>
#include <linux/of.h>
-#include <mach/map.h>
+#define S3C2410_WTCON 0x00
+#define S3C2410_WTDAT 0x04
+#define S3C2410_WTCNT 0x08
-#undef S3C_VA_WATCHDOG
-#define S3C_VA_WATCHDOG (0)
+#define S3C2410_WTCON_RSTEN (1 << 0)
+#define S3C2410_WTCON_INTEN (1 << 2)
+#define S3C2410_WTCON_ENABLE (1 << 5)
-#include <plat/regs-watchdog.h>
+#define S3C2410_WTCON_DIV16 (0 << 3)
+#define S3C2410_WTCON_DIV32 (1 << 3)
+#define S3C2410_WTCON_DIV64 (2 << 3)
+#define S3C2410_WTCON_DIV128 (3 << 3)
+
+#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
+#define S3C2410_WTCON_PRESCALE_MASK (0xff << 8)
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)