Hi,

On Fri, Jan 11, 2013 at 05:56:28PM +0800, Peter Chen wrote:
> It changes the driver to use platform_device_id rather than cpu_is_xxx
> to determine the SoC type, and updates the platform code accordingly.
> 
> Compile ok at imx_v6_v7_defconfig with CONFIG_USB_FSL_USB2 enable.
> Tested at mx51 bbg board, it works ok after enable phy clock
> (Need another patch to fix this problem)
> 
> Signed-off-by: Peter Chen <peter.c...@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 +-
>  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                  |   17 +++----
>  drivers/usb/gadget/fsl_udc_core.c                 |   52 +++++++++++++-------
>  drivers/usb/gadget/fsl_usb2_udc.h                 |   13 ++++--
>  include/linux/fsl_devices.h                       |    8 +++
>  11 files changed, 82 insertions(+), 54 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");
> 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));
>  }
> diff --git a/drivers/usb/gadget/fsl_mxc_udc.c 
> b/drivers/usb/gadget/fsl_mxc_udc.c
> index 1b0f086..f313085 100644
> --- a/drivers/usb/gadget/fsl_mxc_udc.c
> +++ b/drivers/usb/gadget/fsl_mxc_udc.c
> @@ -18,8 +18,6 @@
>  #include <linux/platform_device.h>
>  #include <linux/io.h>
>  
> -#include <mach/hardware.h>
> -
>  static struct clk *mxc_ahb_clk;
>  static struct clk *mxc_per_clk;
>  static struct clk *mxc_ipg_clk;
> @@ -28,7 +26,7 @@ static struct clk *mxc_ipg_clk;
>  #define USBPHYCTRL_OTGBASE_OFFSET    0x608
>  #define USBPHYCTRL_EVDO                      (1 << 23)
>  
> -int fsl_udc_clk_init(struct platform_device *pdev)
> +int fsl_udc_clk_init(enum fsl_udc_type devtype, struct platform_device *pdev)
>  {
>       struct fsl_usb2_platform_data *pdata;
>       unsigned long freq;
> @@ -59,7 +57,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
>       clk_prepare_enable(mxc_per_clk);
>  
>       /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
> -     if (!cpu_is_mx51()) {
> +     if (!(devtype == IMX51_UDC)) {
>               freq = clk_get_rate(mxc_per_clk);
>               if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
>                   (freq < 59999000 || freq > 60001000)) {
> @@ -79,19 +77,18 @@ eclkrate:
>       return ret;
>  }
>  
> -void fsl_udc_clk_finalize(struct platform_device *pdev)
> +void fsl_udc_clk_finalize(enum fsl_udc_type devtype,
> +     struct platform_device *pdev)
>  {
>       struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
> -     if (cpu_is_mx35()) {
> +     if (devtype == IMX35_UDC) {
>               unsigned int v;
>  
>               /* workaround ENGcm09152 for i.MX35 */
>               if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
> -                     v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
> -                                     USBPHYCTRL_OTGBASE_OFFSET));
> +                     v = readl(pdata->regs + USBPHYCTRL_OTGBASE_OFFSET);
>                       writel(v | USBPHYCTRL_EVDO,
> -                             MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
> -                                     USBPHYCTRL_OTGBASE_OFFSET));
> +                             pdata->regs + USBPHYCTRL_OTGBASE_OFFSET);
>               }
>       }
>  
> diff --git a/drivers/usb/gadget/fsl_udc_core.c 
> b/drivers/usb/gadget/fsl_udc_core.c
> index c19f7f1..9f9005b 100644
> --- a/drivers/usb/gadget/fsl_udc_core.c
> +++ b/drivers/usb/gadget/fsl_udc_core.c
> @@ -41,6 +41,7 @@
>  #include <linux/fsl_devices.h>
>  #include <linux/dmapool.h>
>  #include <linux/delay.h>
> +#include <linux/of_device.h>
>  
>  #include <asm/byteorder.h>
>  #include <asm/io.h>
> @@ -2438,17 +2439,13 @@ static int __init fsl_udc_probe(struct 
> platform_device *pdev)
>       unsigned int i;
>       u32 dccparams;
>  
> -     if (strcmp(pdev->name, driver_name)) {
> -             VDBG("Wrong device");
> -             return -ENODEV;
> -     }
> -
>       udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
>       if (udc_controller == NULL) {
>               ERR("malloc udc failed\n");
>               return -ENOMEM;
>       }
>  
> +     udc_controller->devtype = pdev->id_entry->driver_data;
>       pdata = pdev->dev.platform_data;
>       udc_controller->pdata = pdata;
>       spin_lock_init(&udc_controller->lock);
> @@ -2505,7 +2502,7 @@ static int __init fsl_udc_probe(struct platform_device 
> *pdev)
>  #endif
>  
>       /* Initialize USB clocks */
> -     ret = fsl_udc_clk_init(pdev);
> +     ret = fsl_udc_clk_init(udc_controller->devtype, pdev);
>       if (ret < 0)
>               goto err_iounmap_noclk;
>  
> @@ -2547,7 +2544,7 @@ static int __init fsl_udc_probe(struct platform_device 
> *pdev)
>               dr_controller_setup(udc_controller);
>       }
>  
> -     fsl_udc_clk_finalize(pdev);
> +     fsl_udc_clk_finalize(udc_controller->devtype, pdev);
>  
>       /* Setup gadget structure */
>       udc_controller->gadget.ops = &fsl_gadget_ops;
> @@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
>  
>       return fsl_udc_resume(NULL);
>  }
> -
>  /*-------------------------------------------------------------------------
>       Register entry point for the peripheral controller driver
>  --------------------------------------------------------------------------*/
> -
> +static struct platform_device_id fsl_udc_devtype[] = {

should be const

> +     {
> +             .name = "imx-udc-mx25",
> +             .driver_data = IMX25_UDC,
> +     }, {
> +             .name = "imx-udc-mx27",
> +             .driver_data = IMX27_UDC,
> +     }, {
> +             .name = "imx-udc-mx31",
> +             .driver_data = IMX31_UDC,
> +     }, {
> +             .name = "imx-udc-mx35",
> +             .driver_data = IMX35_UDC,
> +     }, {
> +             .name = "imx-udc-mx51",
> +             .driver_data = IMX51_UDC,
> +     }
> +};
> +MODULE_DEVICE_TABLE(platform, fsl_udc_devtype);
>  static struct platform_driver udc_driver = {
> -     .remove  = __exit_p(fsl_udc_remove),
> +     .remove         = __exit_p(fsl_udc_remove),
> +     /* Just for FSL i.mx SoC currently */
> +     .id_table       = fsl_udc_devtype,
>       /* these suspend and resume are not usb suspend and resume */
> -     .suspend = fsl_udc_suspend,
> -     .resume  = fsl_udc_resume,
> -     .driver  = {
> -             .name = (char *)driver_name,
> -             .owner = THIS_MODULE,
> -             /* udc suspend/resume called from OTG driver */
> -             .suspend = fsl_udc_otg_suspend,
> -             .resume  = fsl_udc_otg_resume,
> +     .suspend        = fsl_udc_suspend,
> +     .resume         = fsl_udc_resume,
> +     .driver         = {
> +                     .name = (char *)driver_name,
> +                     .owner = THIS_MODULE,
> +                     /* udc suspend/resume called from OTG driver */
> +                     .suspend = fsl_udc_otg_suspend,
> +                     .resume  = fsl_udc_otg_resume,
>       },
>  };
>  
> diff --git a/drivers/usb/gadget/fsl_usb2_udc.h 
> b/drivers/usb/gadget/fsl_usb2_udc.h
> index f61a967..bc1f6d0 100644
> --- a/drivers/usb/gadget/fsl_usb2_udc.h
> +++ b/drivers/usb/gadget/fsl_usb2_udc.h
> @@ -505,6 +505,8 @@ struct fsl_udc {
>       u32 ep0_dir;            /* Endpoint zero direction: can be
>                                  USB_DIR_IN or USB_DIR_OUT */
>       u8 device_address;      /* Device USB address */
> +     /* devtype for kinds of SoC, only i.mx uses it now */
> +     enum fsl_udc_type devtype;

to me this looks wrong as it will grow forever. Are you sure you don't
have a way to detect the revision in runtime ?

BTW, it looks to me that, in order to remove cpu_is_*() from that
driver, all you have to do is:

diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index 1b0f086..f06102d 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -18,8 +18,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
-
 static struct clk *mxc_ahb_clk;
 static struct clk *mxc_per_clk;
 static struct clk *mxc_ipg_clk;
@@ -59,14 +57,12 @@ int fsl_udc_clk_init(struct platform_device *pdev)
        clk_prepare_enable(mxc_per_clk);
 
        /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
-       if (!cpu_is_mx51()) {
-               freq = clk_get_rate(mxc_per_clk);
-               if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
-                   (freq < 59999000 || freq > 60001000)) {
-                       dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", 
freq);
-                       ret = -EINVAL;
-                       goto eclkrate;
-               }
+       freq = clk_get_rate(mxc_per_clk);
+       if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
+                       (freq < 59999000 || freq > 60001000)) {
+               dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
+               ret = -EINVAL;
+               goto eclkrate;
        }
 
        return 0;
@@ -82,17 +78,15 @@ eclkrate:
 void fsl_udc_clk_finalize(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-       if (cpu_is_mx35()) {
-               unsigned int v;
+       unsigned int v;
 
-               /* workaround ENGcm09152 for i.MX35 */
-               if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
-                       v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
+       /* workaround ENGcm09152 for i.MX35 */
+       if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
+               v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
                                        USBPHYCTRL_OTGBASE_OFFSET));
-                       writel(v | USBPHYCTRL_EVDO,
+               writel(v | USBPHYCTRL_EVDO,
                                MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
                                        USBPHYCTRL_OTGBASE_OFFSET));
-               }
        }
 
        /* ULPI transceivers don't need usbpll */


The only problem is that you're accessing PHY address space directly
without even ioremap() it first, not to mention that PHY address space
should only be accessed by a PHY (drivers/usb/phy) driver.

All of these details are all fixed in chipidea. More and more I consider
just deleting this driver and forcing you guys to use chipidea.

That whole MX35_IO_ADDRESS() is really wrong. It shouldn't be used
outside of arch/mach-imx/, that's why it sits in a mach/ header.

As I said before, this patch is too big for -rc and is unnecessary
considering patch I wrote above. Note that there is no problems in
checking if ULPI PHY clk is 60MHz on all arches and, for the workaround,
you already have a runtime check.

Shawn, it can be broken down into smaller pieces because you can *FIX
THE COMPILE BREAKAGE* with a very small patch as above (only issue now
is usage of MX32_IO_ADDRESS()).

-- 
balbi

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to