LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 2/3] usb: fsl_mxc_udc: replace MX35_IO_ADDRESS to ioremap
From: Peter Chen @ 2013-01-15  2:29 UTC (permalink / raw)
  To: shawn.guo, balbi, kernel, gregkh, r58472
  Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1358216975-1404-1-git-send-email-peter.chen@freescale.com>

As mach/hardware.h is deleted, we can't visit platform code at driver.
It has no phy driver to combine with this controller, so it has to use
ioremap to map phy address as a workaround.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/gadget/fsl_mxc_udc.c  |   30 +++++++++++++++++++++++-------
 drivers/usb/gadget/fsl_udc_core.c |    4 +++-
 drivers/usb/gadget/fsl_usb2_udc.h |    5 +++--
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index 1176bd8..bb65c46 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -23,7 +23,8 @@ static struct clk *mxc_per_clk;
 static struct clk *mxc_ipg_clk;
 
 /* workaround ENGcm09152 for i.MX35 */
-#define USBPHYCTRL_OTGBASE_OFFSET	0x608
+#define MX35_USBPHYCTRL_OFFSET		0x600
+#define USBPHYCTRL_OTGBASE_OFFSET	0x8
 #define USBPHYCTRL_EVDO			(1 << 23)
 
 int fsl_udc_clk_init(struct platform_device *pdev)
@@ -77,25 +78,40 @@ eclkrate:
 	return ret;
 }
 
-void fsl_udc_clk_finalize(struct platform_device *pdev)
+int fsl_udc_clk_finalize(struct platform_device *pdev)
 {
 	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-	unsigned int v;
+	int ret = 0;
 
 	/* workaround ENGcm09152 for i.MX35 */
 	if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
-		v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
-				USBPHYCTRL_OTGBASE_OFFSET));
+		unsigned int v;
+		struct resource *res = platform_get_resource
+			(pdev, IORESOURCE_MEM, 0);
+		void __iomem *phy_regs = ioremap(res->start +
+						MX35_USBPHYCTRL_OFFSET, 512);
+		if (!phy_regs) {
+			dev_err(&pdev->dev, "ioremap for phy address fails\n");
+			ret = -EINVAL;
+			goto ioremap_err;
+		}
+
+		v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
 		writel(v | USBPHYCTRL_EVDO,
-			MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
-				USBPHYCTRL_OTGBASE_OFFSET));
+			phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
+
+		iounmap(phy_regs);
 	}
 
+
+ioremap_err:
 	/* ULPI transceivers don't need usbpll */
 	if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
 		clk_disable_unprepare(mxc_per_clk);
 		mxc_per_clk = NULL;
 	}
+
+	return ret;
 }
 
 void fsl_udc_clk_release(void)
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index c971e84..347b1ed 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -2543,7 +2543,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 		dr_controller_setup(udc_controller);
 	}
 
-	fsl_udc_clk_finalize(pdev);
+	ret = fsl_udc_clk_finalize(pdev);
+	if (ret)
+		goto err_free_irq;
 
 	/* Setup gadget structure */
 	udc_controller->gadget.ops = &fsl_gadget_ops;
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index f61a967..c6703bb 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -592,15 +592,16 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
 struct platform_device;
 #ifdef CONFIG_ARCH_MXC
 int fsl_udc_clk_init(struct platform_device *pdev);
-void fsl_udc_clk_finalize(struct platform_device *pdev);
+int fsl_udc_clk_finalize(struct platform_device *pdev);
 void fsl_udc_clk_release(void);
 #else
 static inline int fsl_udc_clk_init(struct platform_device *pdev)
 {
 	return 0;
 }
-static inline void fsl_udc_clk_finalize(struct platform_device *pdev)
+static inline int fsl_udc_clk_finalize(struct platform_device *pdev)
 {
+	return 0;
 }
 static inline void fsl_udc_clk_release(void)
 {
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH v5 3/3] ARM: i.MX clock: Change the connection-id for fsl-usb2-udc
From: Peter Chen @ 2013-01-15  2:29 UTC (permalink / raw)
  To: shawn.guo, balbi, kernel, gregkh, r58472
  Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1358216975-1404-1-git-send-email-peter.chen@freescale.com>

As we use platform_device_id for fsl-usb2-udc driver, it needs to
change clk connection-id, or the related devm_clk_get will be failed.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 arch/arm/mach-imx/clk-imx25.c       |    6 +++---
 arch/arm/mach-imx/clk-imx27.c       |    6 +++---
 arch/arm/mach-imx/clk-imx31.c       |    6 +++---
 arch/arm/mach-imx/clk-imx35.c       |    6 +++---
 arch/arm/mach-imx/clk-imx51-imx53.c |    6 +++---
 5 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index b197aa7..67e353d 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -254,9 +254,9 @@ int __init mx25_clocks_init(void)
 	clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
 	clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
 	clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
-	clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
+	clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx25");
+	clk_register_clkdev(clk[usbotg_ahb], "ahb", "imx-udc-mx25");
+	clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx25");
 	clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0");
 	/* i.mx25 has the i.mx35 type cspi */
 	clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 4c1d1e4..1ffe3b5 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -236,9 +236,9 @@ int __init mx27_clocks_init(unsigned long fref)
 	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
 	clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0");
 	clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0");
-	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
+	clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
+	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "imx-udc-mx27");
+	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "imx-udc-mx27");
 	clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
 	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
 	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
index 8be64e0..ef66eaf 100644
--- a/arch/arm/mach-imx/clk-imx31.c
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -139,9 +139,9 @@ int __init mx31_clocks_init(unsigned long fref)
 	clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
 	clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
 	clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
-	clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
-	clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
+	clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx31");
+	clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx31");
+	clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx31");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	/* i.mx31 has the i.mx21 type uart */
 	clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index 66f3d65..69fe9c8 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -251,9 +251,9 @@ int __init mx35_clocks_init()
 	clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
 	clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
 	clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
-	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
-	clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
+	clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx35");
+	clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx35");
+	clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx35");
 	clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
 	clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 579023f..fb7cb84 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -269,9 +269,9 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 	clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
 	clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
 	clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
-	clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc");
-	clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc");
+	clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51");
+	clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51");
+	clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51");
 	clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand");
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
-- 
1.7.0.4

^ permalink raw reply related

* Re: 3.7-rc7: BUG: MAX_STACK_TRACE_ENTRIES too low!
From: Li Zhong @ 2013-01-15  6:59 UTC (permalink / raw)
  To: Christian Kujau; +Cc: paulus, linuxppc-dev, LKML
In-Reply-To: <alpine.DEB.2.01.1301121241340.7378@trent.utfs.org>

On Sat, 2013-01-12 at 12:43 -0800, Christian Kujau wrote:
> On Wed, 28 Nov 2012 at 16:41, Li Zhong wrote:
> > On Tue, 2012-11-27 at 19:22 -0800, Christian Kujau wrote:
> > > On Tue, 27 Nov 2012 at 19:06, Christian Kujau wrote:
> > > > the same thing[0] happened again in 3.7-rc7, after ~20h uptime:
> > > 
> > > I found the following on patchwork, but this seems to deal with powerpc64 
> > > only, while this PowerBook G4 of mine is powerpc32:
> > > 
> > >   http://patchwork.ozlabs.org/patch/193414/
> > > 
> > > It looks related, but then again, I fail to parse assember...
> > 
> > Hi Christian, 
> > 
> > Would you please help to try the following fix? I don't have a powerpc32
> > machine for test...
> 
> The patch hasn't made it into mainline yet. Any chance that this will be 
> included in 3.8?

I don't know...

FYI, it is already in the next of ppc tree 
http://git.kernel.org/?p=linux/kernel/git/benh/powerpc.git;a=shortlog;h=refs/heads/next

I guess it would get into 3.9, at least. 

Thanks, Zhong

> 
> Thanks,
> Christian.
> 
> > ==============================================
> > diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
> > index 9499385..cadebfd 100644
> > --- a/arch/powerpc/kernel/entry_32.S
> > +++ b/arch/powerpc/kernel/entry_32.S
> > @@ -439,6 +439,8 @@ ret_from_fork:
> >  ret_from_kernel_thread:
> >  	REST_NVGPRS(r1)
> >  	bl	schedule_tail
> > +	li	r3,0
> > +	stw	r3,0(r1)
> >  	mtlr	r14
> >  	mr	r3,r15
> >  	PPC440EP_ERR42
> > ==============================================
> > 
> > > 
> > > Christian.
> > > 
> > > > [40007.339487] [sched_delayed] sched: RT throttling activated
> > > > [69731.388717] BUG: MAX_STACK_TRACE_ENTRIES too low!
> > > > [69731.390371] turning off the locking correctness validator.
> > > > [69731.391942] Call Trace:
> > > > [69731.393525] [c9a61c10] [c0009064] show_stack+0x70/0x1bc (unreliable)
> > > > [69731.395152] [c9a61c50] [c0077460] save_trace+0xfc/0x114
> > > > [69731.396735] [c9a61c60] [c007be20] __lock_acquire+0x1568/0x19b8
> > > > [69731.398296] [c9a61d00] [c007c2c0] lock_acquire+0x50/0x70
> > > > [69731.399857] [c9a61d20] [c0550e28] _raw_spin_lock_irq+0x5c/0x78
> > > > [69731.401419] [c9a61d40] [c054fb58] __schedule+0xd8/0x534
> > > > [69731.402972] [c9a61da0] [c0550094] _cond_resched+0x50/0x68
> > > > [69731.404527] [c9a61db0] [c0479908] dst_gc_task+0xbc/0x258
> > > > [69731.406070] [c9a61e40] [c004eeb8] process_one_work+0x1f4/0x49c
> > > > [69731.407585] [c9a61e80] [c004f644] worker_thread+0x14c/0x400
> > > > [69731.409075] [c9a61eb0] [c0057634] kthread+0xbc/0xc0
> > > > [69731.410521] [c9a61f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
> > > > [...repeated 54 times...]
> > > > 
> > > > Anyone knows what this is about?
> > > > 
> > > > Thanks,
> > > > Christian.
> > > > 
> > > > [0] http://lkml.indiana.edu/hypermail/linux/kernel/1211.0/03025.html
> > 
> > 
> > 
> 

^ permalink raw reply

* [PATCH 0/3] Enable multiple MSI feature in pSeries
From: Mike Qiu @ 2013-01-15  7:38 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel; +Cc: tglx, Mike Qiu

Currently, multiple MSI feature hasn't been enabled in pSeries,
These patches try to enbale this feature.

These patches have been tested by using ipr driver, and the driver patch
has been made by Wen Xiong <wenxiong@linux.vnet.ibm.com>:

[PATCH 0/7] Add support for new IBM SAS controllers

Test platform: One partition of pSeries with one cpu core(4 SMTs) and 
               RAID bus controller: IBM PCI-E IPR SAS Adapter (ASIC) in POWER7
OS version: SUSE Linux Enterprise Server 11 SP2  (ppc64) with 3.8-rc3 kernel 

IRQ 21 and 22 are assigned to the ipr device which support 2 mutiple MSI.

The test results is shown by 'cat /proc/interrups':
          CPU0       CPU1       CPU2       CPU3       
16:     240458     261601     226310     200425      XICS Level     IPI
17:          0          0          0          0      XICS Level     RAS_EPOW
18:         10          0          3          2      XICS Level     hvc_console
19:     122182      28481      28527      28864      XICS Level     ibmvscsi
20:        506    7388226        108        118      XICS Level     eth0
21:          6          5          5          5      XICS Level     host1-0
22:        817        814        816        813      XICS Level     host1-1
LOC:     398077     316725     231882     203049   Local timer interrupts
SPU:       1659        919        961        903   Spurious interrupts
CNT:          0          0          0          0   Performance
monitoring interrupts
MCE:          0          0          0          0   Machine check exceptions

Mike Qiu (3):
  irq: Set multiple MSI descriptor data for multiple IRQs
  irq: Add hw continuous IRQs map to virtual continuous IRQs support
  powerpc/pci: Enable pSeries multiple MSI feature

 arch/powerpc/kernel/msi.c            |    4 --
 arch/powerpc/platforms/pseries/msi.c |   62 ++++++++++++++++++++++++++++++++-
 include/linux/irq.h                  |    4 ++
 include/linux/irqdomain.h            |    3 ++
 kernel/irq/chip.c                    |   40 ++++++++++++++++-----
 kernel/irq/irqdomain.c               |   61 +++++++++++++++++++++++++++++++++
 6 files changed, 158 insertions(+), 16 deletions(-)

-- 
1.7.7.6

^ permalink raw reply

* [PATCH 2/3] irq: Add hw continuous IRQs map to virtual continuous IRQs support
From: Mike Qiu @ 2013-01-15  7:38 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel; +Cc: tglx, Mike Qiu
In-Reply-To: <1358235536-32741-1-git-send-email-qiudayu@linux.vnet.ibm.com>

Adding a function irq_create_mapping_many() which can associate
multiple MSIs to a continous irq mapping.

This is needed to enable multiple MSI support for pSeries.

Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
---
 include/linux/irq.h       |    2 +
 include/linux/irqdomain.h |    3 ++
 kernel/irq/irqdomain.c    |   61 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 60ef45b..e00a7ec 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -592,6 +592,8 @@ int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
 #define irq_alloc_desc_from(from, node)		\
 	irq_alloc_descs(-1, from, 1, node)
 
+#define irq_alloc_desc_n(nevc, node)		\
+	irq_alloc_descs(-1, 0, nevc, node)
 void irq_free_descs(unsigned int irq, unsigned int cnt);
 int irq_reserve_irqs(unsigned int from, unsigned int cnt);
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 0d5b17b..831dded 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -168,6 +168,9 @@ extern int irq_create_strict_mappings(struct irq_domain *domain,
 				      unsigned int irq_base,
 				      irq_hw_number_t hwirq_base, int count);
 
+extern int irq_create_mapping_many(struct irq_domain *domain,
+					irq_hw_number_t hwirq_base, int count);
+
 static inline int irq_create_identity_mapping(struct irq_domain *host,
 					      irq_hw_number_t hwirq)
 {
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 96f3a1d..38648e6 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -636,6 +636,67 @@ int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base,
 }
 EXPORT_SYMBOL_GPL(irq_create_strict_mappings);
 
+/**
+ * irq_create_mapping_many - Map a range of hw IRQs to a range of virtual IRQs
+ * @domain: domain owning the interrupt range
+ * @hwirq_base: beginning of continuous hardware IRQ range
+ * @count: Number of interrupts to map
+ *
+ * This routine is used for allocating and mapping a range of hardware
+ * irqs to virtual IRQs where the virtual irq numbers are not at pre-defined
+ * locations.
+ *
+ * Greater than 0 is returned upon success, while any failure to establish a
+ * static mapping is treated as an error.
+ */
+int irq_create_mapping_many(struct irq_domain *domain,
+		irq_hw_number_t hwirq_base, int count)
+{
+	int ret, irq_base;
+	int virq, i;
+
+	pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq_base);
+
+	/* Look for default domain if nececssary */
+	if (!domain)
+		domain = irq_default_domain;
+	if (!domain) {
+		pr_warn("irq_create_mapping called for NULL domain, hwirq=%lx\n"
+			, hwirq_base);
+		WARN_ON(1);
+		return 0;
+	}
+	pr_debug("-> using domain @%p\n", domain);
+
+	/* For IRQ_DOMAIN_MAP_LEGACY, get the first virtual interrupt number */
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return irq_domain_legacy_revmap(domain, hwirq_base);
+
+	/* Check if mapping already exists */
+	for (i = 0; i < count; i++) {
+		virq = irq_find_mapping(domain, hwirq_base+i);
+		if (virq) {
+			pr_debug("existing mapping on virq %d,"
+					" now dispose it first\n", virq);
+			irq_dispose_mapping(virq);
+		}
+	}
+
+	/* Allocate the continuous virtual interrupt numbers */
+	irq_base = irq_alloc_desc_n(count, of_node_to_nid(domain->of_node));
+	if (unlikely(irq_base < 0))
+		return  irq_base;
+
+	ret = irq_domain_associate_many(domain, irq_base, hwirq_base, count);
+	if (unlikely(ret < 0)) {
+		irq_free_descs(irq_base, count);
+		return ret;
+	}
+
+	return irq_base;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping_many);
+
 unsigned int irq_create_of_mapping(struct device_node *controller,
 				   const u32 *intspec, unsigned int intsize)
 {
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH 1/3] irq: Set multiple MSI descriptor data for multiple IRQs
From: Mike Qiu @ 2013-01-15  7:38 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel; +Cc: tglx, Mike Qiu
In-Reply-To: <1358235536-32741-1-git-send-email-qiudayu@linux.vnet.ibm.com>

Multiple MSI only requires the IRQ in msi_desc entry to be set as
the value of irq_base.

This patch implements the above mentioned technique.

Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
---
 include/linux/irq.h |    2 ++
 kernel/irq/chip.c   |   40 ++++++++++++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index fdf2c4a..60ef45b 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -528,6 +528,8 @@ extern int irq_set_handler_data(unsigned int irq, void *data);
 extern int irq_set_chip_data(unsigned int irq, void *data);
 extern int irq_set_irq_type(unsigned int irq, unsigned int type);
 extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry);
+extern int irq_set_multiple_msi_desc(unsigned int irq_base, unsigned int nvec,
+					struct msi_desc *entry);
 extern struct irq_data *irq_get_irq_data(unsigned int irq);
 
 static inline struct irq_chip *irq_get_chip(unsigned int irq)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3aca9f2..c4c39d3 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -90,6 +90,35 @@ int irq_set_handler_data(unsigned int irq, void *data)
 EXPORT_SYMBOL(irq_set_handler_data);
 
 /**
+ *	irq_set_multiple_msi_desc - set Multiple MSI descriptor data
+ *	for multiple IRQs
+ *	@irq_base:	Interrupt number base
+ *	@nvec:	The number of interrupts
+ *	@entry:	Pointer to MSI descriptor data
+ *
+ *	Set IRQ descriptors for multiple MSIs
+ */
+int irq_set_multiple_msi_desc(unsigned int irq_base, unsigned int nvec,
+				struct msi_desc *entry)
+{
+	unsigned long flags, i;
+	struct irq_desc *desc;
+
+	for (i = 0; i < nvec; i++) {
+		desc = irq_get_desc_lock(irq_base + i, &flags,
+					IRQ_GET_DESC_CHECK_GLOBAL);
+		if (!desc)
+			return -EINVAL;
+		desc->irq_data.msi_desc = entry;
+		if (i == 0 && entry)
+			entry->irq = irq_base;
+		irq_put_desc_unlock(desc, flags);
+	}
+
+	return 0;
+}
+
+/**
  *	irq_set_msi_desc - set MSI descriptor data for an irq
  *	@irq:	Interrupt number
  *	@entry:	Pointer to MSI descriptor data
@@ -98,16 +127,7 @@ EXPORT_SYMBOL(irq_set_handler_data);
  */
 int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
 {
-	unsigned long flags;
-	struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
-	if (!desc)
-		return -EINVAL;
-	desc->irq_data.msi_desc = entry;
-	if (entry)
-		entry->irq = irq;
-	irq_put_desc_unlock(desc, flags);
-	return 0;
+	return irq_set_multiple_msi_desc(irq, 1, entry);
 }
 
 /**
-- 
1.7.7.6

^ permalink raw reply related

* [PATCH 3/3] powerpc/pci: Enable pSeries multiple MSI feature
From: Mike Qiu @ 2013-01-15  7:38 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel; +Cc: tglx, Mike Qiu
In-Reply-To: <1358235536-32741-1-git-send-email-qiudayu@linux.vnet.ibm.com>

PCI devices support MSI, MSIX as well as multiple MSI.
But pSeries does not support multiple MSI yet.

This patch enable multiple MSI feature in pSeries.

Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/msi.c            |    4 --
 arch/powerpc/platforms/pseries/msi.c |   62 ++++++++++++++++++++++++++++++++-
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 8bbc12d..46b1470 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -20,10 +20,6 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
 		return -ENOSYS;
 	}
 
-	/* PowerPC doesn't support multiple MSI yet */
-	if (type == PCI_CAP_ID_MSI && nvec > 1)
-		return 1;
-
 	if (ppc_md.msi_check_device) {
 		pr_debug("msi: Using platform check routine.\n");
 		return ppc_md.msi_check_device(dev, nvec, type);
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index e5b0847..6633b18 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -132,13 +132,17 @@ static int rtas_query_irq_number(struct pci_dn *pdn, int offset)
 static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
 {
 	struct msi_desc *entry;
+	int nvec, i;
 
 	list_for_each_entry(entry, &pdev->msi_list, list) {
 		if (entry->irq == NO_IRQ)
 			continue;
 
 		irq_set_msi_desc(entry->irq, NULL);
-		irq_dispose_mapping(entry->irq);
+		nvec = entry->msi_attrib.is_msix ? 1 : 1 <<
+					entry->msi_attrib.multiple;
+		for (i = 0; i < nvec; i++)
+			irq_dispose_mapping(entry->irq + i);
 	}
 
 	rtas_disable_msi(pdev);
@@ -392,6 +396,55 @@ static int check_msix_entries(struct pci_dev *pdev)
 	return 0;
 }
 
+static int setup_multiple_msi_irqs(struct pci_dev *pdev, int nvec)
+{
+	struct pci_dn *pdn;
+	int hwirq, virq_base, i, hwirq_base = 0;
+	struct msi_desc *entry;
+	struct msi_msg msg;
+
+	pdn = get_pdn(pdev);
+	entry = list_entry(pdev->msi_list.next, typeof(*entry), list);
+
+	/*
+	 * Get the hardware IRQ base and ensure the retrieved
+	 * hardware IRQs are continuous
+	 */
+	for (i = 0; i < nvec; i++) {
+		hwirq = rtas_query_irq_number(pdn, i);
+		if (i == 0)
+			hwirq_base = hwirq;
+
+		if (hwirq < 0 || hwirq != (hwirq_base + i)) {
+			pr_debug("rtas_msi: Failure to get %d IRQs on"
+				"PCI device %04x:%02x:%02x.%01x\n", nvec,
+				pci_domain_nr(pdev->bus), pdev->bus->number,
+				PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+			return hwirq;
+		}
+	}
+
+	virq_base = irq_create_mapping_many(NULL, hwirq_base, nvec);
+	if (virq_base <= 0) {
+		pr_debug("rtas_msi: Failure to map IRQs (%d, %d) "
+			"for PCI device %04x:%02x:%02x.%01x\n",
+			hwirq_base, nvec, pci_domain_nr(pdev->bus),
+			pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn));
+		return -ENOSPC;
+	}
+
+	entry->msi_attrib.multiple = ilog2(nvec & 0x3f);
+	irq_set_multiple_msi_desc(virq_base, nvec, entry);
+	for (i = 0; i < nvec; i++) {
+		/* Read config space back so we can restore after reset */
+		read_msi_msg(virq_base + i, &msg);
+		entry->msg = msg;
+	}
+
+	return 0;
+}
+
 static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
 {
 	struct pci_dn *pdn;
@@ -444,11 +497,16 @@ again:
 		return rc;
 	}
 
+	if (type == PCI_CAP_ID_MSI && nvec > 1) {
+		rc = setup_multiple_msi_irqs(pdev, nvec);
+		return rc;
+	}
+
 	i = 0;
 	list_for_each_entry(entry, &pdev->msi_list, list) {
 		hwirq = rtas_query_irq_number(pdn, i++);
 		if (hwirq < 0) {
-			pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
+			pr_debug("rtas_msi: error (%d) getting hwirq\n", nvec);
 			return hwirq;
 		}
 
-- 
1.7.7.6

^ permalink raw reply related

* device tree entry for tsi148
From: ternaryd @ 2013-01-15  8:11 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

I'm trying to install linux on an e500v2 board with the tsi148
VME-Bridge, but got stuck. Now it seems that I need to include
information regarding this bridge into the .dts-file, but can't figure
out how. Maybe somebody on this list could post the tsi148-specific
part of a device tree, which I could use as a guide line?

Please CC me, as I'm not on this list.

Thanks in advance,

-- 
Christoph

^ permalink raw reply

* Re: device tree entry for tsi148
From: Martyn Welch @ 2013-01-15  9:32 UTC (permalink / raw)
  To: ternaryd; +Cc: linuxppc-dev
In-Reply-To: <20130115091119.41e2a0f9@vesta>

On 15/01/13 08:11, ternaryd wrote:
> Hi,
> 
> I'm trying to install linux on an e500v2 board with the tsi148
> VME-Bridge, but got stuck. Now it seems that I need to include
> information regarding this bridge into the .dts-file, but can't figure
> out how. Maybe somebody on this list could post the tsi148-specific
> part of a device tree, which I could use as a guide line?
> 

You don't need to include anything about the device it's self, but there will
need to be an entry in the DTS for PCI. Which SOC are you using?

Can you provide your boot log?

Martyn


-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189

^ permalink raw reply

* [RFC][v0][PATCH 1/1] ppc64: ignore interrupts while offline
From: Tiejun Chen @ 2013-01-15 10:31 UTC (permalink / raw)
  To: benh, galak; +Cc: linuxppc-dev, linux-kernel

With lazy interrupt, some implementations of hotplug will
get some interrupts even while offline, just ignore these.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
 arch/powerpc/kernel/irq.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4f97fe3..dbca574 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -144,6 +144,12 @@ notrace unsigned int __check_irq_replay(void)
 	 */
 	unsigned char happened = local_paca->irq_happened;
 
+	/* Some implementations of hotplug will get some interrupts while
+	 * offline, just ignore these.
+	 */
+	if (cpu_is_offline(smp_processor_id()))
+		return 0;
+
 	/* Clear bit 0 which we wouldn't clear otherwise */
 	local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
 
-- 
1.7.9.5

^ permalink raw reply related

* [BUG Fix Patch 0/6] Bug fix for physical memory hot-remove.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev

Hi Andrew,

Here are some bug fix patches for physical hot-remove patches.
And there are some new ones reported by others, I'll fix them soon.

Thanks. :)


Tang Chen (6):
  Bug fix: Hold spinlock across find|remove /sys/firmware/memmap/X
    operation.
  Bug fix: Do not calculate direct mapping pages when freeing vmemmap
    pagetables.
  Bug fix: Do not free direct mapping pages twice.
  Bug fix: Do not free page split from hugepage one by one.
  Bug fix: Fix the wrong comments of map_entries.
  Bug fix: Reuse the storage of /sys/firmware/memmap/X/ allocated by
    bootmem.

 arch/x86/mm/init_64.c     |   92 ++++++++++++++++++++++++++++-----
 drivers/firmware/memmap.c |  124 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 179 insertions(+), 37 deletions(-)

^ permalink raw reply

* [BUG Fix Patch 2/6] Bug fix: Do not calculate direct mapping pages when freeing vmemmap pagetables.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

We only need to update direct_pages_count[level] when we freeing direct mapped
pagetables.

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
 arch/x86/mm/init_64.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e829113..368cc3f 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -804,14 +804,13 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 		if (IS_ALIGNED(addr, PAGE_SIZE) &&
 		    IS_ALIGNED(next, PAGE_SIZE)) {
-			if (!direct) {
+			if (!direct)
 				free_pagetable(pte_page(*pte), 0);
-				pages++;
-			}
 
 			spin_lock(&init_mm.page_table_lock);
 			pte_clear(&init_mm, addr, pte);
 			spin_unlock(&init_mm.page_table_lock);
+			pages++;
 		} else {
 			/*
 			 * If we are not removing the whole page, it means
@@ -824,11 +823,11 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 			if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
 				free_pagetable(pte_page(*pte), 0);
-				pages++;
 
 				spin_lock(&init_mm.page_table_lock);
 				pte_clear(&init_mm, addr, pte);
 				spin_unlock(&init_mm.page_table_lock);
+				pages++;
 			}
 		}
 	}
@@ -857,15 +856,14 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 		if (pmd_large(*pmd)) {
 			if (IS_ALIGNED(addr, PMD_SIZE) &&
 			    IS_ALIGNED(next, PMD_SIZE)) {
-				if (!direct) {
+				if (!direct)
 					free_pagetable(pmd_page(*pmd),
 						       get_order(PMD_SIZE));
-					pages++;
-				}
 
 				spin_lock(&init_mm.page_table_lock);
 				pmd_clear(pmd);
 				spin_unlock(&init_mm.page_table_lock);
+				pages++;
 				continue;
 			}
 
@@ -914,15 +912,14 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 		if (pud_large(*pud)) {
 			if (IS_ALIGNED(addr, PUD_SIZE) &&
 			    IS_ALIGNED(next, PUD_SIZE)) {
-				if (!direct) {
+				if (!direct)
 					free_pagetable(pud_page(*pud),
 						       get_order(PUD_SIZE));
-					pages++;
-				}
 
 				spin_lock(&init_mm.page_table_lock);
 				pud_clear(pud);
 				spin_unlock(&init_mm.page_table_lock);
+				pages++;
 				continue;
 			}
 
-- 
1.7.1

^ permalink raw reply related

* [BUG Fix Patch 1/6] Bug fix: Hold spinlock across find|remove /sys/firmware/memmap/X operation.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

It is unsafe to return an entry pointer and release the map_entries_lock. So we should
not hold the map_entries_lock separately in firmware_map_find_entry() and
firmware_map_remove_entry(). Hold the map_entries_lock across find and remove
/sys/firmware/memmap/X operation.

And also, users of these two functions need to be careful to hold the lock when using
these two functions.

The suggestion is from Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
 drivers/firmware/memmap.c |   25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 4211da5..940c4e9 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -150,12 +150,12 @@ static int firmware_map_add_entry(u64 start, u64 end,
  * firmware_map_remove_entry() - Does the real work to remove a firmware
  * memmap entry.
  * @entry: removed entry.
+ *
+ * The caller must hold map_entries_lock, and release it properly.
  **/
 static inline void firmware_map_remove_entry(struct firmware_map_entry *entry)
 {
-	spin_lock(&map_entries_lock);
 	list_del(&entry->list);
-	spin_unlock(&map_entries_lock);
 }
 
 /*
@@ -188,23 +188,28 @@ static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
 }
 
 /*
- * Search memmap entry
+ * firmware_map_find_entry: Search memmap entry.
+ * @start: Start of the memory range.
+ * @end:   End of the memory range (exclusive).
+ * @type:  Type of the memory range.
+ *
+ * This function is to find the memmap entey of a given memory range.
+ * The caller must hold map_entries_lock, and must not release the lock
+ * until the processing of the returned entry has completed.
+ *
+ * Return pointer to the entry to be found on success, or NULL on failure.
  */
-
 static struct firmware_map_entry * __meminit
 firmware_map_find_entry(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
-	spin_lock(&map_entries_lock);
 	list_for_each_entry(entry, &map_entries, list)
 		if ((entry->start == start) && (entry->end == end) &&
 		    (!strcmp(entry->type, type))) {
-			spin_unlock(&map_entries_lock);
 			return entry;
 		}
 
-	spin_unlock(&map_entries_lock);
 	return NULL;
 }
 
@@ -274,11 +279,15 @@ int __meminit firmware_map_remove(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
+	spin_lock(&map_entries_lock);
 	entry = firmware_map_find_entry(start, end - 1, type);
-	if (!entry)
+	if (!entry) {
+		spin_unlock(&map_entries_lock);
 		return -EINVAL;
+	}
 
 	firmware_map_remove_entry(entry);
+	spin_unlock(&map_entries_lock);
 
 	/* remove the memmap entry */
 	remove_sysfs_fw_map_entry(entry);
-- 
1.7.1

^ permalink raw reply related

* [BUG Fix Patch 5/6] Bug fix: Fix the wrong comments of map_entries.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

Now we have a map_entries_lock to protect map_entries list.
So we need to update the comments.

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
 drivers/firmware/memmap.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 940c4e9..ae823b4 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -108,11 +108,7 @@ static struct kobj_type memmap_ktype = {
  * Registration functions ------------------------------------------------------
  */
 
-/*
- * Firmware memory map entries. No locking is needed because the
- * firmware_map_add() and firmware_map_add_early() functions are called
- * in firmware initialisation code in one single thread of execution.
- */
+/* Firmware memory map entries. */
 static LIST_HEAD(map_entries);
 static DEFINE_SPINLOCK(map_entries_lock);
 
-- 
1.7.1

^ permalink raw reply related

* [BUG Fix Patch 3/6] Bug fix: Do not free direct mapping pages twice.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

Direct mapped pages were freed when they were offlined, or they were
not allocated. So we only need to free vmemmap pages, no need to free
direct mapped pages.

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
 arch/x86/mm/init_64.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 368cc3f..e77d312 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -804,6 +804,10 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 		if (IS_ALIGNED(addr, PAGE_SIZE) &&
 		    IS_ALIGNED(next, PAGE_SIZE)) {
+			/*
+			 * Do not free direct mapping pages since they were
+			 * freed when offlining.
+			 */
 			if (!direct)
 				free_pagetable(pte_page(*pte), 0);
 
@@ -819,10 +823,11 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 			 * remove the page when it is wholly filled with 0xFD.
 			 */
 			memset((void *)addr, PAGE_INUSE, next - addr);
-			page_addr = page_address(pte_page(*pte));
 
+			page_addr = page_address(pte_page(*pte));
 			if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
-				free_pagetable(pte_page(*pte), 0);
+				if (!direct)
+					free_pagetable(pte_page(*pte), 0);
 
 				spin_lock(&init_mm.page_table_lock);
 				pte_clear(&init_mm, addr, pte);
-- 
1.7.1

^ permalink raw reply related

* [BUG Fix Patch 4/6] Bug fix: Do not free page split from hugepage one by one.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

When we split a larger page into smaller ones, we should not free them
one by one because only the _count of the first page struct makes sense.
Otherwise, the kernel will panic.

So fulfill the unused small pages with 0xFD, and when the whole larger
page is fulfilled with 0xFD, free the whole larger page.

The call trace is like the following:

[ 1052.819430] ------------[ cut here ]------------
[ 1052.874575] kernel BUG at include/linux/mm.h:278!
[ 1052.930754] invalid opcode: 0000 [#1] SMP
[ 1052.979888] Modules linked in: ip6table_filter ip6_tables ebtable_nat ebtables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ipt_REJECT xt_CHECKSUM iptable_mangle iptable_filter ip_tables bridge stp llc sunrpc binfmt_misc dm_mirror dm_region_hash dm_log dm_mod vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support coretemp kvm_intel kvm crc32c_intel microcode pcspkr sg i2c_i801 i2c_core lpc_ich mfd_core ioatdma e1000e i7core_edac edac_core igb dca ptp pps_core sd_mod crc_t10dif megaraid_sas mptsas mptscsih mptbase scsi_transport_sas scsi_mod
[ 1053.580111] CPU 0
[ 1053.602026] Pid: 4, comm: kworker/0:0 Tainted: G        W    3.8.0-rc2-memory-hotremove+ #3 FUJITSU-SV PRIMEQUEST 1800E/SB
[ 1053.736188] RIP: 0010:[<ffffffff81175bd7>]  [<ffffffff81175bd7>] __free_pages+0x37/0x50
[ 1053.831952] RSP: 0018:ffff8807bdcb37f8  EFLAGS: 00010246
[ 1053.895403] RAX: 0000000000000000 RBX: ffff88077c401000 RCX: 000000000000002c
[ 1053.980660] RDX: ffff8807fffd7000 RSI: 0000000000000000 RDI: ffffea001df10040
[ 1054.065917] RBP: ffff8807bdcb37f8 R08: 0000000000000000 R09: 0000000000000000
[ 1054.151178] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
[ 1054.236433] R13: ffffea0040008000 R14: ffffea0040002000 R15: 00003ffffffff000
[ 1054.321691] FS:  0000000000000000(0000) GS:ffff8807c1a00000(0000) knlGS:0000000000000000
[ 1054.418372] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1054.487015] CR2: 00007fbc137ad000 CR3: 0000000001c0c000 CR4: 00000000000007f0
[ 1054.572272] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1054.657533] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 1054.742797] Process kworker/0:0 (pid: 4, threadinfo ffff8807bdcb2000, task ffff8807bde18000)
[ 1054.843628] Stack:
[ 1054.867622]  ffff8807bdcb3818 ffffffff81175ccf 000000077c401000 ffff880796349008
[ 1054.956421]  ffff8807bdcb3848 ffffffff816a16e2 ffffea0040001000 ffff880796349008
[ 1055.045227]  ffffea0040008000 ffffea0040002000 ffff8807bdcb38b8 ffffffff816a181c
[ 1055.134033] Call Trace:
[ 1055.163230]  [<ffffffff81175ccf>] free_pages+0x5f/0x70
[ 1055.224611]  [<ffffffff816a16e2>] free_pagetable+0x7f/0xee
[ 1055.290147]  [<ffffffff816a181c>] remove_pte_table+0xcb/0x1cd
[ 1055.358806]  [<ffffffff81055bd0>] ? leave_mm+0x50/0x50
[ 1055.420187]  [<ffffffff810df55d>] ? trace_hardirqs_on+0xd/0x10
[ 1055.489882]  [<ffffffff816a1f8b>] remove_pmd_table+0x191/0x253
[ 1055.559576]  [<ffffffff816a261e>] remove_pud_table+0x194/0x24d
[ 1055.629270]  [<ffffffff811bbc3f>] ? sparse_remove_one_section+0x2f/0x150
[ 1055.709348]  [<ffffffff816a278c>] remove_pagetable+0xb5/0x17c
[ 1055.778002]  [<ffffffff81692f28>] vmemmap_free+0x18/0x20
[ 1055.841465]  [<ffffffff811bbd15>] sparse_remove_one_section+0x105/0x150
[ 1055.920508]  [<ffffffff811c953c>] __remove_pages+0xec/0x110
[ 1055.987087]  [<ffffffff81692fa7>] arch_remove_memory+0x77/0xc0
[ 1056.056781]  [<ffffffff81694138>] remove_memory+0xb8/0xf0
[ 1056.121284]  [<ffffffff814040aa>] acpi_memory_device_remove+0x76/0xbc
[ 1056.198244]  [<ffffffff813c1e50>] acpi_device_remove+0x90/0xb2
[ 1056.267941]  [<ffffffff8146bf3c>] __device_release_driver+0x7c/0xf0
[ 1056.342824]  [<ffffffff8146c0bf>] device_release_driver+0x2f/0x50
[ 1056.415635]  [<ffffffff813c3142>] acpi_bus_remove+0x32/0x6d
[ 1056.482215]  [<ffffffff813c320e>] acpi_bus_trim+0x91/0x102
[ 1056.547755]  [<ffffffff813c3307>] acpi_bus_hot_remove_device+0x88/0x180
[ 1056.626794]  [<ffffffff813be152>] acpi_os_execute_deferred+0x27/0x34
[ 1056.702717]  [<ffffffff81091c5e>] process_one_work+0x20e/0x5c0
[ 1056.772411]  [<ffffffff81091bef>] ? process_one_work+0x19f/0x5c0
[ 1056.844184]  [<ffffffff813be12b>] ? acpi_os_wait_events_complete+0x23/0x23
[ 1056.926337]  [<ffffffff81093cfe>] worker_thread+0x12e/0x370
[ 1056.992908]  [<ffffffff81093bd0>] ? manage_workers+0x180/0x180
[ 1057.062602]  [<ffffffff81099e3e>] kthread+0xee/0x100
[ 1057.121913]  [<ffffffff810e10b9>] ? __lock_release+0x129/0x190
[ 1057.191609]  [<ffffffff81099d50>] ? __init_kthread_worker+0x70/0x70
[ 1057.266494]  [<ffffffff816b33ac>] ret_from_fork+0x7c/0xb0
[ 1057.330992]  [<ffffffff81099d50>] ? __init_kthread_worker+0x70/0x70
[ 1057.405863] Code: 85 c0 74 27 f0 ff 4f 1c 0f 94 c0 84 c0 74 0a 85 f6 74 11 90 e8 bb e3 ff ff c9 c3 66 0f 1f 84 00 00 00 00 00 e8 1b fe ff ff c9 c3 <0f> 0b 0f 1f 80 00 00 00 00 eb f7 66 66 66 66 66 2e 0f 1f 84 00
[ 1057.638271] RIP  [<ffffffff81175bd7>] __free_pages+0x37/0x50
[ 1057.705994]  RSP <ffff8807bdcb37f8>
[ 1057.747882] ---[ end trace 0f90e1e054d174f9 ]---
[ 1057.803158] Kernel panic - not syncing: Fatal exception

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 arch/x86/mm/init_64.c |   80 +++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e77d312..ff0206b 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -777,7 +777,7 @@ static bool __meminit free_pud_table(pud_t *pud_start, pgd_t *pgd)
 
 static void __meminit
 remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 bool direct, bool split)
 {
 	unsigned long next, pages = 0;
 	pte_t *pte;
@@ -806,14 +806,30 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 		    IS_ALIGNED(next, PAGE_SIZE)) {
 			/*
 			 * Do not free direct mapping pages since they were
-			 * freed when offlining.
+			 * freed when offlining, or simplely not in use.
+			 *
+			 * Do not free pages split from larger page since only
+			 * the _count of the 1st page struct is available.
+			 * Free the larger page when it is fulfilled with 0xFD.
 			 */
-			if (!direct)
-				free_pagetable(pte_page(*pte), 0);
+			if (!direct) {
+				if (split) {
+					/*
+					 * Fill the split 4KB page with 0xFD.
+					 * When the whole 2MB page is fulfilled
+					 * with 0xFD, it could be freed.
+					 */
+					memset((void *)addr, PAGE_INUSE,
+						PAGE_SIZE);
+				} else
+					free_pagetable(pte_page(*pte), 0);
+			}
 
 			spin_lock(&init_mm.page_table_lock);
 			pte_clear(&init_mm, addr, pte);
 			spin_unlock(&init_mm.page_table_lock);
+
+			/* For non-direct mapping, pages means nothing. */
 			pages++;
 		} else {
 			/*
@@ -824,6 +840,10 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 			 */
 			memset((void *)addr, PAGE_INUSE, next - addr);
 
+			/*
+			 * If the range is not aligned to PAGE_SIZE, then the
+			 * page is definitely not split from larger page.
+			 */
 			page_addr = page_address(pte_page(*pte));
 			if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
 				if (!direct)
@@ -845,11 +865,13 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 static void __meminit
 remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 bool direct, bool split)
 {
 	unsigned long pte_phys, next, pages = 0;
 	pte_t *pte_base;
 	pmd_t *pmd;
+	void *page_addr;
+	bool split_pmd = split, split_pte = false;
 
 	pmd = pmd_start + pmd_index(addr);
 	for (; addr < end; addr = next, pmd++) {
@@ -861,14 +883,32 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 		if (pmd_large(*pmd)) {
 			if (IS_ALIGNED(addr, PMD_SIZE) &&
 			    IS_ALIGNED(next, PMD_SIZE)) {
-				if (!direct)
-					free_pagetable(pmd_page(*pmd),
+				if (!direct) {
+					if (split_pmd) {
+						/*
+						 * Fill the split 2MB page with
+						 * 0xFD. When the whole 1GB page
+						 * is fulfilled with 0xFD, it
+						 * could be freed.
+						 */
+						memset((void *)addr, PAGE_INUSE,
+							PMD_SIZE);
+					} else {
+						free_pagetable(pmd_page(*pmd),
 						       get_order(PMD_SIZE));
+					}
+				}
 
 				spin_lock(&init_mm.page_table_lock);
 				pmd_clear(pmd);
 				spin_unlock(&init_mm.page_table_lock);
+
+				/*
+				 * For non-direct mapping, pages means
+				 * nothing.
+				 */
 				pages++;
+
 				continue;
 			}
 
@@ -880,6 +920,7 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 			BUG_ON(!pte_base);
 			__split_large_page((pte_t *)pmd, addr,
 					   (pte_t *)pte_base);
+			split_pte = true;
 
 			spin_lock(&init_mm.page_table_lock);
 			pmd_populate_kernel(&init_mm, pmd, __va(pte_phys));
@@ -889,7 +930,16 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 		}
 
 		pte_base = (pte_t *)map_low_page((pte_t *)pmd_page_vaddr(*pmd));
-		remove_pte_table(pte_base, addr, next, direct);
+		remove_pte_table(pte_base, addr, next, direct, split_pte);
+
+		if (!direct && split_pte) {
+			page_addr = page_address(pmd_page(*pmd));
+			if (!memchr_inv(page_addr, PAGE_INUSE, PMD_SIZE)) {
+				free_pagetable(pmd_page(*pmd),
+					       get_order(PMD_SIZE));
+			}
+		}
+
 		free_pte_table(pte_base, pmd);
 		unmap_low_page(pte_base);
 	}
@@ -906,6 +956,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 	unsigned long pmd_phys, next, pages = 0;
 	pmd_t *pmd_base;
 	pud_t *pud;
+	void *page_addr;
+	bool split_pmd = false;
 
 	pud = pud_start + pud_index(addr);
 	for (; addr < end; addr = next, pud++) {
@@ -936,6 +988,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 			BUG_ON(!pmd_base);
 			__split_large_page((pte_t *)pud, addr,
 					   (pte_t *)pmd_base);
+			split_pmd = true;
 
 			spin_lock(&init_mm.page_table_lock);
 			pud_populate(&init_mm, pud, __va(pmd_phys));
@@ -945,7 +998,16 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 		}
 
 		pmd_base = (pmd_t *)map_low_page((pmd_t *)pud_page_vaddr(*pud));
-		remove_pmd_table(pmd_base, addr, next, direct);
+		remove_pmd_table(pmd_base, addr, next, direct, split_pmd);
+
+		if (!direct && split_pmd) {
+			page_addr = page_address(pud_page(*pud));
+			if (!memchr_inv(page_addr, PAGE_INUSE, PUD_SIZE)) {
+				free_pagetable(pud_page(*pud),
+					       get_order(PUD_SIZE));
+			}
+		}
+
 		free_pmd_table(pmd_base, pud);
 		unmap_low_page(pmd_base);
 	}
-- 
1.7.1

^ permalink raw reply related

* [BUG Fix Patch 6/6] Bug fix: Reuse the storage of /sys/firmware/memmap/X/ allocated by bootmem.
From: Tang Chen @ 2013-01-15 10:54 UTC (permalink / raw)
  To: akpm, rientjes, len.brown, benh, paulus, cl, minchan.kim,
	kosaki.motohiro, isimatu.yasuaki, wujianguo, wency, tangchen, hpa,
	linfeng, laijs, mgorman, yinghai, glommer, jiang.liu
  Cc: linux-s390, linux-ia64, linux-acpi, linux-sh, x86, linux-kernel,
	cmetcalf, linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <1358247267-18089-1-git-send-email-tangchen@cn.fujitsu.com>

Now we don't free firmware_map_entry which is allocated by bootmem because
there is no way to do so when the system is up. But we can at least remember
the address of that memory and reuse the storage when the memory is added
next time.

This patch introduces a new list map_entries_bootmem to link the map entries
allocated by bootmem when they are removed, and a lock to protect it.
And these entries will be reused when the memory is hot-added again.

The idea is suggestted by Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
 drivers/firmware/memmap.c |  103 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index ae823b4..0710179 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -53,6 +53,9 @@ static ssize_t start_show(struct firmware_map_entry *entry, char *buf);
 static ssize_t end_show(struct firmware_map_entry *entry, char *buf);
 static ssize_t type_show(struct firmware_map_entry *entry, char *buf);
 
+static struct firmware_map_entry * __meminit
+firmware_map_find_entry(u64 start, u64 end, const char *type);
+
 /*
  * Static data -----------------------------------------------------------------
  */
@@ -80,6 +83,19 @@ static const struct sysfs_ops memmap_attr_ops = {
 	.show = memmap_attr_show,
 };
 
+/* Firmware memory map entries. */
+static LIST_HEAD(map_entries);
+static DEFINE_SPINLOCK(map_entries_lock);
+
+/*
+ * For memory hotplug, there is no way to free memory map entries allocated
+ * by boot mem after the system is up. So when we hot-remove memory whose
+ * map entry is allocated by bootmem, we need to remember the storage and
+ * reuse it when the memory is hot-added again.
+ */
+static LIST_HEAD(map_entries_bootmem);
+static DEFINE_SPINLOCK(map_entries_bootmem_lock);
+
 
 static inline struct firmware_map_entry *
 to_memmap_entry(struct kobject *kobj)
@@ -91,9 +107,22 @@ static void release_firmware_map_entry(struct kobject *kobj)
 {
 	struct firmware_map_entry *entry = to_memmap_entry(kobj);
 
-	if (PageReserved(virt_to_page(entry)))
-		/* There is no way to free memory allocated from bootmem */
+	if (PageReserved(virt_to_page(entry))) {
+		/*
+		 * Remember the storage allocated by bootmem, and reuse it when
+		 * the memory is hot-added again. The entry will be added to
+		 * map_entries_bootmem here, and deleted from &map_entries in
+		 * firmware_map_remove_entry().
+		 */
+		if (firmware_map_find_entry(entry->start, entry->end,
+		    entry->type)) {
+			spin_lock(&map_entries_bootmem_lock);
+			list_add(&entry->list, &map_entries_bootmem);
+			spin_unlock(&map_entries_bootmem_lock);
+		}
+
 		return;
+	}
 
 	kfree(entry);
 }
@@ -108,10 +137,6 @@ static struct kobj_type memmap_ktype = {
  * Registration functions ------------------------------------------------------
  */
 
-/* Firmware memory map entries. */
-static LIST_HEAD(map_entries);
-static DEFINE_SPINLOCK(map_entries_lock);
-
 /**
  * firmware_map_add_entry() - Does the real work to add a firmware memmap entry.
  * @start: Start of the memory range.
@@ -184,23 +209,25 @@ static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
 }
 
 /*
- * firmware_map_find_entry: Search memmap entry.
+ * firmware_map_find_entry_in_list: Search memmap entry in a given list.
  * @start: Start of the memory range.
  * @end:   End of the memory range (exclusive).
  * @type:  Type of the memory range.
+ * @list:  In which to find the entry.
  *
- * This function is to find the memmap entey of a given memory range.
- * The caller must hold map_entries_lock, and must not release the lock
- * until the processing of the returned entry has completed.
+ * This function is to find the memmap entey of a given memory range in a
+ * given list. The caller must hold map_entries_lock, and must not release
+ * the lock until the processing of the returned entry has completed.
  *
  * Return pointer to the entry to be found on success, or NULL on failure.
  */
 static struct firmware_map_entry * __meminit
-firmware_map_find_entry(u64 start, u64 end, const char *type)
+firmware_map_find_entry_in_list(u64 start, u64 end, const char *type,
+				struct list_head *list)
 {
 	struct firmware_map_entry *entry;
 
-	list_for_each_entry(entry, &map_entries, list)
+	list_for_each_entry(entry, list, list)
 		if ((entry->start == start) && (entry->end == end) &&
 		    (!strcmp(entry->type, type))) {
 			return entry;
@@ -209,6 +236,42 @@ firmware_map_find_entry(u64 start, u64 end, const char *type)
 	return NULL;
 }
 
+/*
+ * firmware_map_find_entry: Search memmap entry in map_entries.
+ * @start: Start of the memory range.
+ * @end:   End of the memory range (exclusive).
+ * @type:  Type of the memory range.
+ *
+ * This function is to find the memmap entey of a given memory range.
+ * The caller must hold map_entries_lock, and must not release the lock
+ * until the processing of the returned entry has completed.
+ *
+ * Return pointer to the entry to be found on success, or NULL on failure.
+ */
+static struct firmware_map_entry * __meminit
+firmware_map_find_entry(u64 start, u64 end, const char *type)
+{
+	return firmware_map_find_entry_in_list(start, end, type, &map_entries);
+}
+
+/*
+ * firmware_map_find_entry_bootmem: Search memmap entry in map_entries_bootmem.
+ * @start: Start of the memory range.
+ * @end:   End of the memory range (exclusive).
+ * @type:  Type of the memory range.
+ *
+ * This function is similar to firmware_map_find_entry except that it find the
+ * given entry in map_entries_bootmem.
+ *
+ * Return pointer to the entry to be found on success, or NULL on failure.
+ */
+static struct firmware_map_entry * __meminit
+firmware_map_find_entry_bootmem(u64 start, u64 end, const char *type)
+{
+	return firmware_map_find_entry_in_list(start, end, type,
+					       &map_entries_bootmem);
+}
+
 /**
  * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
  * memory hotplug.
@@ -226,9 +289,19 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
-	entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
-	if (!entry)
-		return -ENOMEM;
+	entry = firmware_map_find_entry_bootmem(start, end, type);
+	if (!entry) {
+		entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
+		if (!entry)
+			return -ENOMEM;
+	} else {
+		/* Reuse storage allocated by bootmem. */
+		spin_lock(&map_entries_bootmem_lock);
+		list_del(&entry->list);
+		spin_unlock(&map_entries_bootmem_lock);
+
+		memset(entry, 0, sizeof(*entry));
+	}
 
 	firmware_map_add_entry(start, end, type, entry);
 	/* create the memmap entry */
-- 
1.7.1

^ permalink raw reply related

* Issue with USB Mass storage on P5020
From: Vineeth @ 2013-01-15 13:04 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1575 bytes --]

When i connect my 500GB seagate HD on a P5020DS, its not getting mounted.

This is the dmesg log;
am i supposed to change some configuration ?

/ # dmesg

usb 1-1: new high speed USB device using fsl-ehci and address 5
usb 1-1: configuration #1 chosen from 1 choice
scsi2 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 5
usb-storage: waiting for device to settle before scanning

do_scsi_scan_host

scsi 2:0:0:0: Direct-Access     Seagate  Expansion        0219 PQ: 0 ANSI: 6
sd 2:0:0:0: Attached scsi generic sg0 type 0
usb 1-1: USB disconnect, address 5
sd 2:0:0:0: [sda] the result =  65536
usb-storage: device scan complete
sd 2:0:0:0: [sda] sense_valid = 0
sd 2:0:0:0: [sda] the result =  65536
sd 2:0:0:0: [sda] sense_valid = 0
sd 2:0:0:0: [sda] the result =  65536
sd 2:0:0:0: [sda] sense_valid = 0
*sd 2:0:0:0: [sda] READ CAPACITY failed*
sd 2:0:0:0: [sda] Result: hostbyte=0x01 driverbyte=0x00
sd 2:0:0:0: [sda] Sense not available.
sd 2:0:0:0: [sda] Write Protect is off
sd 2:0:0:0: [sda] Mode Sense: ea 0d 20 84
sd 2:0:0:0: [sda] Assuming drive cache: write through
sd 2:0:0:0: [sda] the result =  65536
sd 2:0:0:0: [sda] sense_valid = 0
sd 2:0:0:0: [sda] the result =  65536
sd 2:0:0:0: [sda] sense_valid = 0
sd 2:0:0:0: [sda] the result =  65536
sd 2:0:0:0: [sda] sense_valid = 0
*sd 2:0:0:0: [sda] READ CAPACITY failed  *
sd 2:0:0:0: [sda] Result: hostbyte=0x01 driverbyte=0x00
sd 2:0:0:0: [sda] Sense not available.
sd 2:0:0:0: [sda] Assuming drive cache: write through
sd 2:0:0:0: [sda] Attached SCSI disk
/ #
/ #
/ #
-- VISUAL --

[-- Attachment #2: Type: text/html, Size: 1874 bytes --]

^ permalink raw reply

* Re: [PATCH v5 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Shawn Guo @ 2013-01-15 14:03 UTC (permalink / raw)
  To: Peter Chen
  Cc: r58472, gregkh, linux-usb, balbi, kernel, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <1358216975-1404-2-git-send-email-peter.chen@freescale.com>

On Tue, Jan 15, 2013 at 10:29:33AM +0800, Peter Chen wrote:
> As mach/hardware.h is deleted, we need to use platform_device_id to
> differentiate SoCs. Besides, one cpu_is_mx35 is useless as it has
> already used pdata to differentiate runtime
> 
> Meanwhile we update the platform code accordingly.
> 
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
>  arch/arm/mach-imx/devices/devices-common.h        |    1 +
>  arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c |   15 ++++---
>  drivers/usb/gadget/fsl_mxc_udc.c                  |   24 +++++-------
>  drivers/usb/gadget/fsl_udc_core.c                 |   42 +++++++++++++--------
>  4 files changed, 45 insertions(+), 37 deletions(-)

Since we are splitting the original patch anyway, it's a bit strange
to me that you are mixing arch/arm/mach-imx and drivers/usb/gadget
in this patch.  I'm fine with it, since I assume all the patches to
go via USB tree anyway.

> 
> diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
> index 6277baf..9bd5777 100644
> --- a/arch/arm/mach-imx/devices/devices-common.h
> +++ b/arch/arm/mach-imx/devices/devices-common.h
> @@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan(
>  
>  #include <linux/fsl_devices.h>
>  struct imx_fsl_usb2_udc_data {
> +	const char *devid;
>  	resource_size_t iobase;
>  	resource_size_t irq;
>  };
> diff --git a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> index 37e4439..fb527c7 100644
> --- a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> +++ b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> @@ -11,35 +11,36 @@
>  #include "../hardware.h"
>  #include "devices-common.h"
>  
> -#define imx_fsl_usb2_udc_data_entry_single(soc)				\
> +#define imx_fsl_usb2_udc_data_entry_single(soc, _devid)			\
>  	{								\
> +		.devid = _devid,					\
>  		.iobase = soc ## _USB_OTG_BASE_ADDR,			\
>  		.irq = soc ## _INT_USB_OTG,				\
>  	}
>  
>  #ifdef CONFIG_SOC_IMX25
>  const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
> -	imx_fsl_usb2_udc_data_entry_single(MX25);
> +	imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx25");
>  #endif /* ifdef CONFIG_SOC_IMX25 */
>  
>  #ifdef CONFIG_SOC_IMX27
>  const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
> -	imx_fsl_usb2_udc_data_entry_single(MX27);
> +	imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27");
>  #endif /* ifdef CONFIG_SOC_IMX27 */
>  
>  #ifdef CONFIG_SOC_IMX31
>  const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
> -	imx_fsl_usb2_udc_data_entry_single(MX31);
> +	imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx31");
>  #endif /* ifdef CONFIG_SOC_IMX31 */
>  
>  #ifdef CONFIG_SOC_IMX35
>  const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
> -	imx_fsl_usb2_udc_data_entry_single(MX35);
> +	imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx35");
>  #endif /* ifdef CONFIG_SOC_IMX35 */
>  
>  #ifdef CONFIG_SOC_IMX51
>  const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst =
> -	imx_fsl_usb2_udc_data_entry_single(MX51);
> +	imx_fsl_usb2_udc_data_entry_single(MX51, "imx-udc-mx51");
>  #endif
>  
>  struct platform_device *__init imx_add_fsl_usb2_udc(
> @@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc(
>  			.flags = IORESOURCE_IRQ,
>  		},
>  	};
> -	return imx_add_platform_device_dmamask("fsl-usb2-udc", -1,
> +	return imx_add_platform_device_dmamask(data->devid, -1,
>  			res, ARRAY_SIZE(res),
>  			pdata, sizeof(*pdata), DMA_BIT_MASK(32));
>  }

<snip>

> +static const struct platform_device_id fsl_udc_devtype[] = {
> +	{
> +		.name = "imx-udc-mx25",
> +	}, {
> +		.name = "imx-udc-mx27",
> +	}, {
> +		.name = "imx-udc-mx31",
> +	}, {
> +		.name = "imx-udc-mx35",
> +	}, {
> +		.name = "imx-udc-mx51",
> +	}
> +};

>From what I understand balbi's comment, he dislikes this full list of
device id.  Instead, he prefers to something like below.

static const struct platform_device_id fsl_udc_devtype[] = {
	{
		.name = "imx-udc-mx27",
	}, {
		.name = "imx-udc-mx51",
	}
};

It basically tells that we are handling two type of devices here, one
is imx-udc-mx27 type and the other is imx-udc-mx51 type, with mx25/31/35
completely compatible with mx27 type.  We choose mx27 instead of mx25
to define the type because mx27 Si came out earlier than mx25.  That
said, we generally choose the earlies SoC name to define a particular
version of IP block, since hardware version is mostly unavailable or
unreliable.

But that also means in platform code which create the platform_device,
you will need to use name "imx-udc-mx27" for even mx25/31/35.

	imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx27");
	imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx27");
	imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx27");

Considering this is a piece of code we will not use for any new
hardware, I'm fine with either way.

So, balbi, it's all your call to accept the series as it is or ask for
another iteration.

Shawn

^ permalink raw reply

* Re: [PATCH] powerpc: added DSCR support to ptrace
From: Benjamin Herrenschmidt @ 2013-01-15 18:17 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: Michael Neuling, linuxppc-dev, linux-kernel
In-Reply-To: <1357885749-14042-1-git-send-email-aik@ozlabs.ru>

On Fri, 2013-01-11 at 17:29 +1100, Alexey Kardashevskiy wrote:
> +static unsigned long get_user_dscr(struct task_struct *task)
> +{
> +       return -EIO;
> +}
> +

Does it make sense to return an error here ? ptrace_get_reg() doesn't
seem to have provisions for returning errors, it just return register
values, there's no way to differenciate an error code from a register
value as far as I can tell...

I'll apply your patch anyway because this is an existing problem with
that function (it already returns -EIO in other circumstances), but I
would like if you could submit a followup patch that changes it to
return the register by value and return a real error code, which can be
then handled properly in the two call sites (ptrace.c and ptrace32.c).

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 6/6][v3] perf: Document the ABI of perf sysfs entries
From: Arnaldo Carvalho de Melo @ 2013-01-15 18:57 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: Andi Kleen, Peter Zijlstra, robert.richter, Greg KH,
	Anton Blanchard, linux-kernel, Stephane Eranian, linuxppc-dev,
	Ingo Molnar, Paul Mackerras, Jiri Olsa
In-Reply-To: <20130110010703.GF32590@us.ibm.com>

Em Wed, Jan 09, 2013 at 05:07:03PM -0800, Sukadev Bhattiprolu escreveu:
> [PATCH 6/6][v3] perf: Document the ABI of perf sysfs entries
> 
> This patchset addes two new sets of files to sysfs:
> 
> 	- generic and POWER-specific perf events in /sys/devices/cpu/events/
> 	- perf event config format in /sys/devices/cpu/format/event
> 
> Document the format of these files which would become part of the ABI.
> 
> Changelog[v3]:
> 	[Greg KH] Include ABI documentation.

Jiri, can I have your ack on this one too?

Greg, all ok now?

- Arnaldo
 
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
>  Documentation/ABI/stable/sysfs-devices-cpu-events |   54 +++++++++++++++++++++
>  Documentation/ABI/stable/sysfs-devices-cpu-format |   27 ++++++++++
>  2 files changed, 81 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/stable/sysfs-devices-cpu-format
> 
> diff --git a/Documentation/ABI/stable/sysfs-devices-cpu-events b/Documentation/ABI/stable/sysfs-devices-cpu-events
> index e69de29..f37d542 100644
> --- a/Documentation/ABI/stable/sysfs-devices-cpu-events
> +++ b/Documentation/ABI/stable/sysfs-devices-cpu-events
> @@ -0,0 +1,54 @@
> +What:		/sys/devices/cpu/events/
> +		/sys/devices/cpu/events/branch-misses
> +		/sys/devices/cpu/events/cache-references
> +		/sys/devices/cpu/events/cache-misses
> +		/sys/devices/cpu/events/stalled-cycles-frontend
> +		/sys/devices/cpu/events/branch-instructions
> +		/sys/devices/cpu/events/stalled-cycles-backend
> +		/sys/devices/cpu/events/instructions
> +		/sys/devices/cpu/events/cpu-cycles
> +
> +Date:		2013/01/08
> +
> +Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
> +
> +Description:	Generic performance monitoring events
> +
> +		A collection of performance monitoring events that may be
> +		supported by many/most CPUs. These events can be monitored
> +		using the 'perf(1)' tool.
> +
> +		The contents of each file would look like:
> +
> +			event=0xNNNN
> +
> +		where 'N' is a hex digit.
> +
> +
> +What: 		/sys/devices/cpu/events/PM_LD_MISS_L1
> +		/sys/devices/cpu/events/PM_LD_REF_L1
> +		/sys/devices/cpu/events/PM_CYC
> +		/sys/devices/cpu/events/PM_BRU_FIN
> +		/sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
> +		/sys/devices/cpu/events/PM_BRU_MPRED
> +		/sys/devices/cpu/events/PM_INST_CMPL
> +		/sys/devices/cpu/events/PM_CMPLU_STALL
> +
> +Date:		2013/01/08
> +
> +Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
> +		Linux Powerpc mailing list <linuxppc-dev@ozlabs.org>
> +
> +Description:	POWER specific performance monitoring events
> +
> +		A collection of performance monitoring events that may be
> +		supported by the POWER CPU. These events can be monitored
> +		using the 'perf(1)' tool.
> +
> +		These events may not be supported by other CPUs.
> +
> +		The contents of each file would look like:
> +
> +			event=0xNNNN
> +
> +		where 'N' is a hex digit.
> diff --git a/Documentation/ABI/stable/sysfs-devices-cpu-format b/Documentation/ABI/stable/sysfs-devices-cpu-format
> new file mode 100644
> index 0000000..b15cfb2
> --- /dev/null
> +++ b/Documentation/ABI/stable/sysfs-devices-cpu-format
> @@ -0,0 +1,27 @@
> +What:		/sys/devices/cpu/format/
> +		/sys/devices/cpu/format/event
> +
> +Date:		2013/01/08
> +
> +Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
> +
> +Description:	Format of performance monitoring events
> +
> +		Each CPU/architecture may use different format to represent
> +		the perf event.  The 'event' file describes the configuration
> +		format of the performance monitoring event on the CPU/system.
> +
> +		The contents of each file would look like:
> +
> +			config:m-n
> +
> +		where m and n are the starting and ending bits that are
> +		used to represent the event.
> +
> +		For example, on POWER,
> +
> +			$ cat /sys/devices/cpu/format/event
> +			config:0-20
> +
> +		meaning that POWER uses the first 20-bits to represent a perf
> +		event.
> -- 
> 1.7.1

^ permalink raw reply

* [PATCH] powerpc/fsl: remove extraneous DIU platform functions
From: Timur Tabi @ 2013-01-15 20:04 UTC (permalink / raw)
  To: Kumar Gala, linuxppc-dev

From: Timur Tabi <timur@freescale.com>

The Freescale DIU driver was recently updated to not require a
set_monitor_port platform function if there is only one monitor port.  This
is the case on the P1022 RDK and the MPC5121 ADS boards.  So now we can
remove those functions.

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 arch/powerpc/platforms/512x/mpc512x_shared.c |    5 -----
 arch/powerpc/platforms/85xx/p1022_rdk.c      |   12 ------------
 2 files changed, 0 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index 35f14fd..c7f47cf 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -68,10 +68,6 @@ struct fsl_diu_shared_fb {
 	bool		in_use;
 };
 
-void mpc512x_set_monitor_port(enum fsl_diu_monitor_port port)
-{
-}
-
 #define DIU_DIV_MASK	0x000000ff
 void mpc512x_set_pixel_clock(unsigned int pixclock)
 {
@@ -303,7 +299,6 @@ void __init mpc512x_setup_diu(void)
 		}
 	}
 
-	diu_ops.set_monitor_port	= mpc512x_set_monitor_port;
 	diu_ops.set_pixel_clock		= mpc512x_set_pixel_clock;
 	diu_ops.valid_monitor_port	= mpc512x_valid_monitor_port;
 	diu_ops.release_bootmem		= mpc512x_release_bootmem;
diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
index 55ffa1c..8c92971 100644
--- a/arch/powerpc/platforms/85xx/p1022_rdk.c
+++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
@@ -35,17 +35,6 @@
 #define CLKDVDR_PXCLK_MASK	0x00FF0000
 
 /**
- * p1022rdk_set_monitor_port: switch the output to a different monitor port
- */
-static void p1022rdk_set_monitor_port(enum fsl_diu_monitor_port port)
-{
-	if (port != FSL_DIU_PORT_DVI) {
-		pr_err("p1022rdk: unsupported monitor port %i\n", port);
-		return;
-	}
-}
-
-/**
  * p1022rdk_set_pixel_clock: program the DIU's clock
  *
  * @pixclock: the wavelength, in picoseconds, of the clock
@@ -124,7 +113,6 @@ static void __init p1022_rdk_setup_arch(void)
 		ppc_md.progress("p1022_rdk_setup_arch()", 0);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-	diu_ops.set_monitor_port	= p1022rdk_set_monitor_port;
 	diu_ops.set_pixel_clock		= p1022rdk_set_pixel_clock;
 	diu_ops.valid_monitor_port	= p1022rdk_valid_monitor_port;
 #endif
-- 
1.7.3.4

^ permalink raw reply related

* Re: [BUG Fix Patch 1/6] Bug fix: Hold spinlock across find|remove /sys/firmware/memmap/X operation.
From: Julian Calaby @ 2013-01-15 22:26 UTC (permalink / raw)
  To: Tang Chen
  Cc: linux-ia64, linux-sh, linux-mm, paulus, hpa, sparclinux, cl,
	linux-s390, x86, linux-acpi, isimatu.yasuaki, linfeng, mgorman,
	kosaki.motohiro, rientjes, len.brown, jiang.liu, wency, cmetcalf,
	glommer, wujianguo, yinghai, laijs, linux-kernel, minchan.kim,
	akpm, linuxppc-dev
In-Reply-To: <1358247267-18089-2-git-send-email-tangchen@cn.fujitsu.com>

Hi Tang,

One minor point.

On Tue, Jan 15, 2013 at 9:54 PM, Tang Chen <tangchen@cn.fujitsu.com> wrote:
> It is unsafe to return an entry pointer and release the map_entries_lock. So we should
> not hold the map_entries_lock separately in firmware_map_find_entry() and
> firmware_map_remove_entry(). Hold the map_entries_lock across find and remove
> /sys/firmware/memmap/X operation.
>
> And also, users of these two functions need to be careful to hold the lock when using
> these two functions.
>
> The suggestion is from Andrew Morton <akpm@linux-foundation.org>
>
> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
> ---
>  drivers/firmware/memmap.c |   25 +++++++++++++++++--------
>  1 files changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
> index 4211da5..940c4e9 100644
> --- a/drivers/firmware/memmap.c
> +++ b/drivers/firmware/memmap.c
> @@ -188,23 +188,28 @@ static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry)
>  }
>
>  /*
> - * Search memmap entry
> + * firmware_map_find_entry: Search memmap entry.
> + * @start: Start of the memory range.
> + * @end:   End of the memory range (exclusive).
> + * @type:  Type of the memory range.
> + *
> + * This function is to find the memmap entey of a given memory range.
> + * The caller must hold map_entries_lock, and must not release the lock
> + * until the processing of the returned entry has completed.
> + *
> + * Return pointer to the entry to be found on success, or NULL on failure.

Why not make this completely kernel-doc compliant as you're already
re-writing the comment?

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
.Plan: http://sites.google.com/site/juliancalaby/

^ permalink raw reply

* Re: [PATCH 6/6][v3] perf: Document the ABI of perf sysfs entries
From: Greg KH @ 2013-01-15 22:47 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Andi Kleen, Peter Zijlstra, robert.richter, Anton Blanchard,
	linux-kernel, Stephane Eranian, linuxppc-dev, Ingo Molnar,
	Paul Mackerras, Sukadev Bhattiprolu, Jiri Olsa
In-Reply-To: <20130115185759.GG5826@ghostprotocols.net>

On Tue, Jan 15, 2013 at 03:57:59PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jan 09, 2013 at 05:07:03PM -0800, Sukadev Bhattiprolu escreveu:
> > [PATCH 6/6][v3] perf: Document the ABI of perf sysfs entries
> > 
> > This patchset addes two new sets of files to sysfs:
> > 
> > 	- generic and POWER-specific perf events in /sys/devices/cpu/events/
> > 	- perf event config format in /sys/devices/cpu/format/event
> > 
> > Document the format of these files which would become part of the ABI.
> > 
> > Changelog[v3]:
> > 	[Greg KH] Include ABI documentation.
> 
> Jiri, can I have your ack on this one too?
> 
> Greg, all ok now?

No objection from me, thanks.

greg k-h

^ permalink raw reply

* Re: [PATCH v5 1/3] usb: fsl-mxc-udc: replace cpu_is_xxx() with platform_device_id
From: Peter Chen @ 2013-01-16  1:48 UTC (permalink / raw)
  To: Shawn Guo
  Cc: r58472, gregkh, linux-usb, balbi, kernel, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <20130115140344.GB6574@S2101-09.ap.freescale.net>

On Tue, Jan 15, 2013 at 10:03:46PM +0800, Shawn Guo wrote:
> On Tue, Jan 15, 2013 at 10:29:33AM +0800, Peter Chen wrote:
> > As mach/hardware.h is deleted, we need to use platform_device_id to
> > differentiate SoCs. Besides, one cpu_is_mx35 is useless as it has
> > already used pdata to differentiate runtime
> > 
> > Meanwhile we update the platform code accordingly.
> > 
> > Signed-off-by: Peter Chen <peter.chen@freescale.com>
> > ---
> >  arch/arm/mach-imx/devices/devices-common.h        |    1 +
> >  arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c |   15 ++++---
> >  drivers/usb/gadget/fsl_mxc_udc.c                  |   24 +++++-------
> >  drivers/usb/gadget/fsl_udc_core.c                 |   42 +++++++++++++--------
> >  4 files changed, 45 insertions(+), 37 deletions(-)
> 
> Since we are splitting the original patch anyway, it's a bit strange
> to me that you are mixing arch/arm/mach-imx and drivers/usb/gadget
> in this patch.  I'm fine with it, since I assume all the patches to
> go via USB tree anyway.
> 
> > 
> > diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
> > index 6277baf..9bd5777 100644
> > --- a/arch/arm/mach-imx/devices/devices-common.h
> > +++ b/arch/arm/mach-imx/devices/devices-common.h
> > @@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan(
> >  
> >  #include <linux/fsl_devices.h>
> >  struct imx_fsl_usb2_udc_data {
> > +	const char *devid;
> >  	resource_size_t iobase;
> >  	resource_size_t irq;
> >  };
> > diff --git a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> > index 37e4439..fb527c7 100644
> > --- a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> > +++ b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
> > @@ -11,35 +11,36 @@
> >  #include "../hardware.h"
> >  #include "devices-common.h"
> >  
> > -#define imx_fsl_usb2_udc_data_entry_single(soc)				\
> > +#define imx_fsl_usb2_udc_data_entry_single(soc, _devid)			\
> >  	{								\
> > +		.devid = _devid,					\
> >  		.iobase = soc ## _USB_OTG_BASE_ADDR,			\
> >  		.irq = soc ## _INT_USB_OTG,				\
> >  	}
> >  
> >  #ifdef CONFIG_SOC_IMX25
> >  const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
> > -	imx_fsl_usb2_udc_data_entry_single(MX25);
> > +	imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx25");
> >  #endif /* ifdef CONFIG_SOC_IMX25 */
> >  
> >  #ifdef CONFIG_SOC_IMX27
> >  const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
> > -	imx_fsl_usb2_udc_data_entry_single(MX27);
> > +	imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27");
> >  #endif /* ifdef CONFIG_SOC_IMX27 */
> >  
> >  #ifdef CONFIG_SOC_IMX31
> >  const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
> > -	imx_fsl_usb2_udc_data_entry_single(MX31);
> > +	imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx31");
> >  #endif /* ifdef CONFIG_SOC_IMX31 */
> >  
> >  #ifdef CONFIG_SOC_IMX35
> >  const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
> > -	imx_fsl_usb2_udc_data_entry_single(MX35);
> > +	imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx35");
> >  #endif /* ifdef CONFIG_SOC_IMX35 */
> >  
> >  #ifdef CONFIG_SOC_IMX51
> >  const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst =
> > -	imx_fsl_usb2_udc_data_entry_single(MX51);
> > +	imx_fsl_usb2_udc_data_entry_single(MX51, "imx-udc-mx51");
> >  #endif
> >  
> >  struct platform_device *__init imx_add_fsl_usb2_udc(
> > @@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc(
> >  			.flags = IORESOURCE_IRQ,
> >  		},
> >  	};
> > -	return imx_add_platform_device_dmamask("fsl-usb2-udc", -1,
> > +	return imx_add_platform_device_dmamask(data->devid, -1,
> >  			res, ARRAY_SIZE(res),
> >  			pdata, sizeof(*pdata), DMA_BIT_MASK(32));
> >  }
> 
> <snip>
> 
> > +static const struct platform_device_id fsl_udc_devtype[] = {
> > +	{
> > +		.name = "imx-udc-mx25",
> > +	}, {
> > +		.name = "imx-udc-mx27",
> > +	}, {
> > +		.name = "imx-udc-mx31",
> > +	}, {
> > +		.name = "imx-udc-mx35",
> > +	}, {
> > +		.name = "imx-udc-mx51",
> > +	}
> > +};
> 
> From what I understand balbi's comment, he dislikes this full list of
> device id.  Instead, he prefers to something like below.
> 
> static const struct platform_device_id fsl_udc_devtype[] = {
> 	{
> 		.name = "imx-udc-mx27",
> 	}, {
> 		.name = "imx-udc-mx51",
> 	}
> };
> 
> It basically tells that we are handling two type of devices here, one
> is imx-udc-mx27 type and the other is imx-udc-mx51 type, with mx25/31/35
> completely compatible with mx27 type.  We choose mx27 instead of mx25
> to define the type because mx27 Si came out earlier than mx25.  That
> said, we generally choose the earlies SoC name to define a particular
> version of IP block, since hardware version is mostly unavailable or
> unreliable.
> 
> But that also means in platform code which create the platform_device,
> you will need to use name "imx-udc-mx27" for even mx25/31/35.
> 
> 	imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx27");
> 	imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx27");
> 	imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx27");
> 
> Considering this is a piece of code we will not use for any new
> hardware, I'm fine with either way.
> 
> So, balbi, it's all your call to accept the series as it is or ask for
> another iteration.
Thanks Shawn. Let's see Felipe's comment, nevertheless, I will send v6 patch
due to a compile error at mx25

> 
> Shawn

-- 

Best Regards,
Peter Chen

^ permalink raw reply


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