From f8db3c9086cd33ee3efc913ade291694f54a57f2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 29 Sep 2013 10:29:11 +0800 Subject: PCI: exynos: Add missing clk_disable_unprepare() on error path Add the missing clk_disable_unprepare() before return from exynos_pcie_probe() in the error handling case. Signed-off-by: Wei Yongjun Signed-off-by: Bjorn Helgaas Acked-by: Jingoo Han diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index ee692c2..8980472 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -599,18 +599,24 @@ static int __init exynos_pcie_probe(struct platform_device *pdev) elbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); exynos_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base); - if (IS_ERR(exynos_pcie->elbi_base)) - return PTR_ERR(exynos_pcie->elbi_base); + if (IS_ERR(exynos_pcie->elbi_base)) { + ret = PTR_ERR(exynos_pcie->elbi_base); + goto fail_bus_clk; + } phy_base = platform_get_resource(pdev, IORESOURCE_MEM, 1); exynos_pcie->phy_base = devm_ioremap_resource(&pdev->dev, phy_base); - if (IS_ERR(exynos_pcie->phy_base)) - return PTR_ERR(exynos_pcie->phy_base); + if (IS_ERR(exynos_pcie->phy_base)) { + ret = PTR_ERR(exynos_pcie->phy_base); + goto fail_bus_clk; + } block_base = platform_get_resource(pdev, IORESOURCE_MEM, 2); exynos_pcie->block_base = devm_ioremap_resource(&pdev->dev, block_base); - if (IS_ERR(exynos_pcie->block_base)) - return PTR_ERR(exynos_pcie->block_base); + if (IS_ERR(exynos_pcie->block_base)) { + ret = PTR_ERR(exynos_pcie->block_base); + goto fail_bus_clk; + } ret = add_pcie_port(pp, pdev); if (ret < 0) -- cgit v0.10.2 From 18edf4512cfa3e3662bdbdfc5f11c2eb20721734 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Wed, 9 Oct 2013 09:12:21 -0600 Subject: PCI: designware: Add header guards Add header guards to prevent redundant inclusion. Signed-off-by: Seungwon Jeon Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index faccbbf..d87fbae 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -11,6 +11,9 @@ * published by the Free Software Foundation. */ +#ifndef _PCIE_DESIGNWARE_H +#define _PCIE_DESIGNWARE_H + struct pcie_port_info { u32 cfg0_size; u32 cfg1_size; @@ -77,3 +80,5 @@ int dw_pcie_host_init(struct pcie_port *pp); int dw_pcie_setup(int nr, struct pci_sys_data *sys); struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys); int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); + +#endif /* _PCIE_DESIGNWARE_H */ -- cgit v0.10.2 From 73e408508bf6c76d8dc06f044f0e4703a1e27f14 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 9 Oct 2013 09:12:37 -0600 Subject: PCI: designware: Make dw_pcie_rd_own_conf(), etc., static The following variables and functions are used only in pcie-designware.c, so make them static: global_io_offset dw_pcie_rd_own_conf() dw_pcie_wr_own_conf() dw_pcie_setup() dw_pcie_scan_bus() dw_pcie_map_irq() Signed-off-by: Bjorn Helgaas Acked-by: Jingoo Han diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 8963017..a2e69af 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -67,7 +67,7 @@ static struct hw_pci dw_pci; -unsigned long global_io_offset; +static unsigned long global_io_offset; static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) { @@ -118,8 +118,8 @@ static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg) writel(val, pp->dbi_base + reg); } -int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, - u32 *val) +static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, + u32 *val) { int ret; @@ -131,8 +131,8 @@ int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, return ret; } -int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, - u32 val) +static int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, + u32 val) { int ret; @@ -667,7 +667,7 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -int dw_pcie_setup(int nr, struct pci_sys_data *sys) +static int dw_pcie_setup(int nr, struct pci_sys_data *sys) { struct pcie_port *pp; @@ -690,7 +690,7 @@ int dw_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) +static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) { struct pci_bus *bus; struct pcie_port *pp = sys_to_pcie(sys); @@ -707,7 +707,7 @@ struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) return bus; } -int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index d87fbae..890c2ce 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -66,19 +66,12 @@ struct pcie_host_ops { void (*host_init)(struct pcie_port *pp); }; -extern unsigned long global_io_offset; - int cfg_read(void __iomem *addr, int where, int size, u32 *val); int cfg_write(void __iomem *addr, int where, int size, u32 val); -int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, u32 val); -int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val); void dw_handle_msi_irq(struct pcie_port *pp); void dw_pcie_msi_init(struct pcie_port *pp); int dw_pcie_link_up(struct pcie_port *pp); void dw_pcie_setup_rc(struct pcie_port *pp); int dw_pcie_host_init(struct pcie_port *pp); -int dw_pcie_setup(int nr, struct pci_sys_data *sys); -struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys); -int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); #endif /* _PCIE_DESIGNWARE_H */ -- cgit v0.10.2 From 904d0e7889933fb48d921c998fd1cabb3a9d6635 Mon Sep 17 00:00:00 2001 From: Pratyush Anand Date: Wed, 9 Oct 2013 21:32:12 +0900 Subject: PCI: designware: Add irq_create_mapping() Without irq_create_mapping(), the correct IRQ number cannot be provided. In this case, it makes problems such as NULL dereference. Thus, irq_create_mapping() should be added for MSI. Suggested-by: Kishon Vijay Abraham I Signed-off-by: Pratyush Anand Signed-off-by: Jingoo Han Signed-off-by: Bjorn Helgaas diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index a2e69af..1e1fea4 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -157,7 +157,7 @@ static struct irq_chip dw_msi_irq_chip = { void dw_handle_msi_irq(struct pcie_port *pp) { unsigned long val; - int i, pos; + int i, pos, irq; for (i = 0; i < MAX_MSI_CTRLS; i++) { dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, @@ -165,8 +165,9 @@ void dw_handle_msi_irq(struct pcie_port *pp) if (val) { pos = 0; while ((pos = find_next_bit(&val, 32, pos)) != 32) { - generic_handle_irq(pp->msi_irq_start - + (i * 32) + pos); + irq = irq_find_mapping(pp->irq_domain, + i * 32 + pos); + generic_handle_irq(irq); pos++; } } @@ -237,9 +238,8 @@ static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) } } - irq = (pp->msi_irq_start + pos0); - - if ((irq + no_irqs) > (pp->msi_irq_start + MAX_MSI_IRQS-1)) + irq = irq_find_mapping(pp->irq_domain, pos0); + if (!irq) goto no_valid_irq; i = 0; @@ -270,6 +270,7 @@ static void clear_irq(unsigned int irq) struct irq_desc *desc; struct msi_desc *msi; struct pcie_port *pp; + struct irq_data *data = irq_get_irq_data(irq); /* get the port structure */ desc = irq_to_desc(irq); @@ -280,7 +281,7 @@ static void clear_irq(unsigned int irq) return; } - pos = irq - pp->msi_irq_start; + pos = data->hwirq; irq_free_desc(irq); @@ -371,8 +372,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) struct of_pci_range range; struct of_pci_range_parser parser; u32 val; - - struct irq_domain *irq_domain; + int i; if (of_pci_range_parser_init(&parser, np)) { dev_err(pp->dev, "missing ranges property\n"); @@ -441,15 +441,16 @@ int __init dw_pcie_host_init(struct pcie_port *pp) } if (IS_ENABLED(CONFIG_PCI_MSI)) { - irq_domain = irq_domain_add_linear(pp->dev->of_node, + pp->irq_domain = irq_domain_add_linear(pp->dev->of_node, MAX_MSI_IRQS, &msi_domain_ops, &dw_pcie_msi_chip); - if (!irq_domain) { + if (!pp->irq_domain) { dev_err(pp->dev, "irq domain init failed\n"); return -ENXIO; } - pp->msi_irq_start = irq_find_mapping(irq_domain, 0); + for (i = 0; i < MAX_MSI_IRQS; i++) + irq_create_mapping(pp->irq_domain, i); } if (pp->ops->host_init) diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index 890c2ce..c15379b 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -50,7 +50,7 @@ struct pcie_port { u32 lanes; struct pcie_host_ops *ops; int msi_irq; - int msi_irq_start; + struct irq_domain *irq_domain; unsigned long msi_data; DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); }; -- cgit v0.10.2 From eb36309a9db9e9e8e8e0813ebbe3a14a58969351 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 21 Oct 2013 14:36:43 +0530 Subject: PCI: exynos: Remove redundant of_match_ptr This driver is DT only. Hence of_match_ptr is not required. Signed-off-by: Sachin Kamat Signed-off-by: Bjorn Helgaas Acked-by: Jingoo Han diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index 8980472..24beed3 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -653,7 +653,7 @@ static struct platform_driver exynos_pcie_driver = { .driver = { .name = "exynos-pcie", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(exynos_pcie_of_match), + .of_match_table = exynos_pcie_of_match, }, }; -- cgit v0.10.2