Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V5] ST SPEAr: PCIE gadget suppport
From: pratyush @ 2011-02-21  8:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298276013-14716-1-git-send-email-y>

Sorry, Please discard this patch.

Regards
Pratyush


On 2/21/2011 1:43 PM, y wrote:
> From: Pratyush Anand <pratyush.anand@st.com>
> 
> This is a configurable gadget. can be configured by configfs interface. Any
> IP available at PCIE bus can be programmed to be used by host
> controller.It supoorts both INTX and MSI.
> By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
> with size 0x1000
> 
> Changes since V4:
> - All documentation related comments incorporated
> 
> Changes since V3:
> - support for multiple instances of such device
> - changes to minimzie portability issue on 64 bit machine
> - unnecessary typecast removed
> - sysfs_streq used in place of complex code
> 
> Changes since V2:
> - driver has been moved from sysfs to configfs
> - Documentation/ABI directory has also been updated
> - typo error in documenation has been corrected
> - clk value is checked after encapsulating by IS_ERR
> 
> Changes since V1:
> - __iomem added for register addresses
> - kerneldoc comment removed whereever not required.
> - help node moved from sysfs to documentation/misc-devices
> - strict_strtoul used instead of sscanf
> 
> Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
> ---
>  .../ABI/testing/configfs-spear-pcie-gadget         |   30 +
>  Documentation/misc-devices/spear-pcie-gadget.txt   |  129 +++
>  drivers/misc/Kconfig                               |   10 +
>  drivers/misc/Makefile                              |    1 +
>  drivers/misc/spear13xx_pcie_gadget.c               |  908 ++++++++++++++++++++
>  5 files changed, 1078 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/configfs-spear-pcie-gadget
>  create mode 100644 Documentation/misc-devices/spear-pcie-gadget.txt
>  create mode 100644 drivers/misc/spear13xx_pcie_gadget.c
> 
> diff --git a/Documentation/ABI/testing/configfs-spear-pcie-gadget b/Documentation/ABI/testing/configfs-spear-pcie-gadget
> new file mode 100644
> index 0000000..29593d0
> --- /dev/null
> +++ b/Documentation/ABI/testing/configfs-spear-pcie-gadget
> @@ -0,0 +1,30 @@
> +What:          /config/pcie-gadget
> +Date:          Feb 2011
> +KernelVersion: 2.6.37
> +Contact:       Pratyush Anand <pratyush.anand@st.com>
> +Description:
> +
> +       Interface is used to configure selected dual mode PCIe controller
> +       as device and then program its various registers to configure it
> +       as a particular device type.
> +       This interfaces can be used to show spear's PCIe device capability.
> +
> +       Nodes are only visible when configfs is mounted. To mount configfs
> +       in /config directory use:
> +       # mount -t configfs none /config/
> +
> +       /config/pcie-gadget/
> +               link ... used to enable ltssm and read its status.
> +               int_type ...used to configure and read type of supported
> +                       interrupt
> +               no_of_msi ... used to configure number of MSI vector needed and
> +                       to read no of MSI granted.
> +               inta ... write 1 to assert INTA and 0 to de-assert.
> +               send_msi ... write MSI vector to be sent.
> +               vendor_id ... used to write and read vendor id (hex)
> +               device_id ... used to write and read device id (hex)
> +               bar0_size ... used to write and read bar0_size
> +               bar0_address ... used to write and read bar0 mapped area in hex.
> +               bar0_rw_offset ... used to write and read offset of bar0 where
> +                       bar0_data will be written or read.
> +               bar0_data ... used to write and read data at bar0_rw_offset.
> diff --git a/Documentation/misc-devices/spear-pcie-gadget.txt b/Documentation/misc-devices/spear-pcie-gadget.txt
> new file mode 100644
> index 0000000..7b86b80
> --- /dev/null
> +++ b/Documentation/misc-devices/spear-pcie-gadget.txt
> @@ -0,0 +1,129 @@
> +Spear PCIe Gadget Driver:
> +
> +Author
> +=============
> +Pratyush Anand (pratyush.anand at st.com)
> +
> +Location
> +============
> +driver/misc/spear13xx_pcie_gadget.c
> +
> +Supported Chip:
> +===================
> +SPEAr1300
> +SPEAr1310
> +
> +Menuconfig option:
> +==========================
> +Device Drivers
> +       Misc devices
> +               PCIe gadget support for SPEAr13XX platform
> +purpose
> +===========
> +This driver has several nodes which can be read/written by configfs interface.
> +Its main purpose is to configure selected dual mode PCIe controller as device
> +and then program its various registers to configure it as a particular device
> +type. This driver can be used to show spear's PCIe device capability.
> +
> +Description of different nodes:
> +=================================
> +
> +read behavior of nodes:
> +------------------------------
> +link           :gives ltssm status.
> +int_type       :type of supported interrupt
> +no_of_msi      :zero if MSI is not enabled by host. A positive value is the
> +               number of MSI vector granted.
> +vendor_id      :returns programmed vendor id (hex)
> +device_id      :returns programmed device id(hex)
> +bar0_size:     :returns size of bar0 in hex.
> +bar0_address   :returns address of bar0 mapped area in hex.
> +bar0_rw_offset :returns offset of bar0 for which bar0_data will return value.
> +bar0_data      :returns data at bar0_rw_offset.
> +
> +write behavior of nodes:
> +------------------------------
> +link           :write UP to enable ltsmm DOWN to disable
> +int_type       :write interrupt type to be configured and (int_type could be
> +               INTA, MSI or NO_INT). Select MSI only when you have programmed
> +               no_of_msi node.
> +no_of_msi      :number of MSI vector needed.
> +inta           :write 1 to assert INTA and 0 to de-assert.
> +send_msi       :write MSI vector to be sent.
> +vendor_id      :write vendor id(hex) to be programmed.
> +device_id      :write device id(hex) to be programmed.
> +bar0_size      :write size of bar0 in hex. default bar0 size is 1000 (hex)
> +               bytes.
> +bar0_address   :write  address of bar0 mapped area in hex. (default mapping of
> +               bar0 is SYSRAM1(E0800000). Always program bar size before bar
> +               address. Kernel might modify bar size and address for alignment, so
> +               read back bar size and address after writing to cross check.
> +bar0_rw_offset :write offset of bar0 for which bar0_data will write value.
> +bar0_data      :write data to be written at bar0_rw_offset.
> +
> +Node programming example
> +===========================
> +Program all PCIe registers in such a way that when this device is connected
> +to the PCIe host, then host sees this device as 1MB RAM.
> +#mount -t configfs none /Config
> +# cd /config/pcie_gadget/
> +Now you have all the nodes in this directory.
> +program vendor id as 0x104a
> +# echo 104A >> vendor_id
> +
> +program device id as 0xCD80
> +# echo CD80 >> device_id
> +
> +program BAR0 size as 1MB
> +# echo 100000 >> bar0_size
> +
> +check for programmed bar0 size
> +# cat bar0_size
> +
> +Program BAR0 Address as DDR (0x2100000). This is the physical address of
> +memory, which is to be made visible to PCIe host. Similarly any other peripheral
> +can also be made visible to PCIe host. E.g., if you program base address of UART
> +as BAR0 address then when this device will be connected to a host, it will be
> +visible as UART.
> +# echo 2100000 >> bar0_address
> +
> +program interrupt type : INTA
> +# echo INTA >> int_type
> +
> +go for link up now.
> +# echo UP >> link
> +
> +It will have to be insured that, once link up is done on gadget, then only host
> +is initialized and start to search PCIe devices on its port.
> +
> +/*wait till link is up*/
> +# cat link
> +wait till it returns UP.
> +
> +To assert INTA
> +# echo 1 >> inta
> +
> +To de-assert INTA
> +# echo 0 >> inta
> +
> +if MSI is to be used as interrupt, program no of msi vector needed (say4)
> +# echo 4 >> no_of_msi
> +
> +select MSI as interrupt type
> +# echo MSI >> int_type
> +
> +go for link up now
> +# echo UP >> link
> +
> +wait till link is up
> +# cat link
> +An application can repetitively read this node till link is found UP. It can
> +sleep between two read.
> +
> +wait till msi is enabled
> +# cat no_of_msi
> +Should return 4 (number of requested MSI vector)
> +
> +to send msi vector 2
> +# echo 2 >> send_msi
> +#cd -
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 4d073f1..dea052d 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -394,6 +394,16 @@ config DS1682
>           This driver can also be built as a module.  If so, the module
>           will be called ds1682.
> 
> +config SPEAR13XX_PCIE_GADGET
> +       bool "PCIe gadget support for SPEAr13XX platform"
> +       depends on ARCH_SPEAR13XX
> +       default n
> +       help
> +        This option enables gadget support for PCIe controller. If
> +        board file defines any controller as PCIe endpoint then a sysfs
> +        entry will be created for that controller. User can use these
> +        sysfs node to configure PCIe EP as per his requirements.
> +
>  config TI_DAC7512
>         tristate "Texas Instruments DAC7512"
>         depends on SPI && SYSFS
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 98009cc..c489536 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
>  obj-$(CONFIG_HMC6352)          += hmc6352.o
>  obj-y                          += eeprom/
>  obj-y                          += cb710/
> +obj-$(CONFIG_SPEAR13XX_PCIE_GADGET)    += spear13xx_pcie_gadget.o
>  obj-$(CONFIG_VMWARE_BALLOON)   += vmw_balloon.o
>  obj-$(CONFIG_ARM_CHARLCD)      += arm-charlcd.o
>  obj-$(CONFIG_PCH_PHUB)         += pch_phub.o
> diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
> new file mode 100644
> index 0000000..ec3b8c9
> --- /dev/null
> +++ b/drivers/misc/spear13xx_pcie_gadget.c
> @@ -0,0 +1,908 @@
> +/*
> + * drivers/misc/spear13xx_pcie_gadget.c
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Pratyush Anand<pratyush.anand@st.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pci_regs.h>
> +#include <linux/configfs.h>
> +#include <mach/pcie.h>
> +#include <mach/misc_regs.h>
> +
> +#define IN0_MEM_SIZE   (200 * 1024 * 1024 - 1)
> +/* In current implementation address translation is done using IN0 only.
> + * So IN1 start address and IN0 end address has been kept same
> +*/
> +#define IN1_MEM_SIZE   (0 * 1024 * 1024 - 1)
> +#define IN_IO_SIZE     (20 * 1024 * 1024 - 1)
> +#define IN_CFG0_SIZE   (12 * 1024 * 1024 - 1)
> +#define IN_CFG1_SIZE   (12 * 1024 * 1024 - 1)
> +#define IN_MSG_SIZE    (12 * 1024 * 1024 - 1)
> +/* Keep default BAR size as 4K*/
> +/* AORAM would be mapped by default*/
> +#define INBOUND_ADDR_MASK      (SPEAR13XX_SYSRAM1_SIZE - 1)
> +
> +#define INT_TYPE_NO_INT        0
> +#define INT_TYPE_INTX  1
> +#define INT_TYPE_MSI   2
> +struct spear_pcie_gadget_config {
> +       void __iomem *base;
> +       void __iomem *va_app_base;
> +       void __iomem *va_dbi_base;
> +       char int_type[10];
> +       ulong requested_msi;
> +       ulong configured_msi;
> +       ulong bar0_size;
> +       ulong bar0_rw_offset;
> +       void __iomem *va_bar0_address;
> +};
> +
> +struct pcie_gadget_target {
> +       struct configfs_subsystem subsys;
> +       struct spear_pcie_gadget_config config;
> +};
> +
> +struct pcie_gadget_target_attr {
> +       struct configfs_attribute       attr;
> +       ssize_t         (*show)(struct spear_pcie_gadget_config *config,
> +                                               char *buf);
> +       ssize_t         (*store)(struct spear_pcie_gadget_config *config,
> +                                                const char *buf,
> +                                                size_t count);
> +};
> +
> +static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg)
> +{
> +       /* Enable DBI access */
> +       writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
> +                       &app_reg->slv_armisc);
> +       writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
> +                       &app_reg->slv_awmisc);
> +
> +}
> +
> +static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg)
> +{
> +       /* disable DBI access */
> +       writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
> +                       &app_reg->slv_armisc);
> +       writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
> +                       &app_reg->slv_awmisc);
> +
> +}
> +
> +static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config,
> +               int where, int size, u32 *val)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       ulong va_address;
> +
> +       /* Enable DBI access */
> +       enable_dbi_access(app_reg);
> +
> +       va_address = (ulong)config->va_dbi_base + (where & ~0x3);
> +
> +       *val = readl(va_address);
> +
> +       if (size == 1)
> +               *val = (*val >> (8 * (where & 3))) & 0xff;
> +       else if (size == 2)
> +               *val = (*val >> (8 * (where & 3))) & 0xffff;
> +
> +       /* Disable DBI access */
> +       disable_dbi_access(app_reg);
> +}
> +
> +static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config,
> +               int where, int size, u32 val)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       ulong va_address;
> +
> +       /* Enable DBI access */
> +       enable_dbi_access(app_reg);
> +
> +       va_address = (ulong)config->va_dbi_base + (where & ~0x3);
> +
> +       if (size == 4)
> +               writel(val, va_address);
> +       else if (size == 2)
> +               writew(val, va_address + (where & 2));
> +       else if (size == 1)
> +               writeb(val, va_address + (where & 3));
> +
> +       /* Disable DBI access */
> +       disable_dbi_access(app_reg);
> +}
> +
> +#define PCI_FIND_CAP_TTL       48
> +
> +static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
> +               u32 pos, int cap, int *ttl)
> +{
> +       u32 id;
> +
> +       while ((*ttl)--) {
> +               spear_dbi_read_reg(config, pos, 1, &pos);
> +               if (pos < 0x40)
> +                       break;
> +               pos &= ~3;
> +               spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
> +               if (id == 0xff)
> +                       break;
> +               if (id == cap)
> +                       return pos;
> +               pos += PCI_CAP_LIST_NEXT;
> +       }
> +       return 0;
> +}
> +
> +static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
> +                       u32 pos, int cap)
> +{
> +       int ttl = PCI_FIND_CAP_TTL;
> +
> +       return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
> +}
> +
> +static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
> +                               u8 hdr_type)
> +{
> +       u32 status;
> +
> +       spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
> +       if (!(status & PCI_STATUS_CAP_LIST))
> +               return 0;
> +
> +       switch (hdr_type) {
> +       case PCI_HEADER_TYPE_NORMAL:
> +       case PCI_HEADER_TYPE_BRIDGE:
> +               return PCI_CAPABILITY_LIST;
> +       case PCI_HEADER_TYPE_CARDBUS:
> +               return PCI_CB_CAPABILITY_LIST;
> +       default:
> +               return 0;
> +       }
> +
> +       return 0;
> +}
> +
> +/*
> + * Tell if a device supports a given PCI capability.
> + * Returns the address of the requested capability structure within the
> + * device's PCI configuration space or 0 in case the device does not
> + * support it. Possible values for @cap:
> + *
> + * %PCI_CAP_ID_PM      Power Management
> + * %PCI_CAP_ID_AGP     Accelerated Graphics Port
> + * %PCI_CAP_ID_VPD     Vital Product Data
> + * %PCI_CAP_ID_SLOTID  Slot Identification
> + * %PCI_CAP_ID_MSI     Message Signalled Interrupts
> + * %PCI_CAP_ID_CHSWP   CompactPCI HotSwap
> + * %PCI_CAP_ID_PCIX    PCI-X
> + * %PCI_CAP_ID_EXP     PCI Express
> + */
> +static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
> +               int cap)
> +{
> +       u32 pos;
> +       u32 hdr_type;
> +
> +       spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
> +
> +       pos = pci_find_own_cap_start(config, hdr_type);
> +       if (pos)
> +               pos = pci_find_own_next_cap(config, pos, cap);
> +
> +       return pos;
> +}
> +
> +static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
> +{
> +       return 0;
> +}
> +
> +/*
> + * configfs interfaces show/store functions
> + */
> +static ssize_t pcie_gadget_show_link(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> +       if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
> +               return sprintf(buf, "UP");
> +       else
> +               return sprintf(buf, "DOWN");
> +}
> +
> +static ssize_t pcie_gadget_store_link(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> +       if (sysfs_streq(buf, "UP"))
> +               writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
> +                       &app_reg->app_ctrl_0);
> +       else if (sysfs_streq(buf, "DOWN"))
> +               writel(readl(&app_reg->app_ctrl_0)
> +                               & ~(1 << APP_LTSSM_ENABLE_ID),
> +                               &app_reg->app_ctrl_0);
> +       else
> +               return -EINVAL;
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_int_type(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       return sprintf(buf, "%s", config->int_type);
> +}
> +
> +static ssize_t pcie_gadget_store_int_type(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       u32 cap, vec, flags;
> +       ulong vector;
> +
> +       if (sysfs_streq(buf, "INTA"))
> +               spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
> +
> +       else if (sysfs_streq(buf, "MSI")) {
> +               vector = config->requested_msi;
> +               vec = 0;
> +               while (vector > 1) {
> +                       vector /= 2;
> +                       vec++;
> +               }
> +               spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
> +               cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
> +               spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
> +               flags &= ~PCI_MSI_FLAGS_QMASK;
> +               flags |= vec << 1;
> +               spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
> +       } else
> +               return -EINVAL;
> +
> +       strcpy(config->int_type, buf);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_no_of_msi(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       u32 cap, vec, flags;
> +       ulong vector;
> +
> +       if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
> +                       != (1 << CFG_MSI_EN_ID))
> +               vector = 0;
> +       else {
> +               cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
> +               spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
> +               flags &= ~PCI_MSI_FLAGS_QSIZE;
> +               vec = flags >> 4;
> +               vector = 1;
> +               while (vec--)
> +                       vector *= 2;
> +       }
> +       config->configured_msi = vector;
> +
> +       return sprintf(buf, "%lu", vector);
> +}
> +
> +static ssize_t pcie_gadget_store_no_of_msi(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       if (strict_strtoul(buf, 0, &config->requested_msi))
> +               return -EINVAL;
> +       if (config->requested_msi > 32)
> +               config->requested_msi = 32;
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_store_inta(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       ulong en;
> +
> +       if (strict_strtoul(buf, 0, &en))
> +               return -EINVAL;
> +
> +       if (en)
> +               writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
> +                               &app_reg->app_ctrl_0);
> +       else
> +               writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
> +                               &app_reg->app_ctrl_0);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_store_send_msi(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       ulong vector;
> +       u32 ven_msi;
> +
> +       if (strict_strtoul(buf, 0, &vector))
> +               return -EINVAL;
> +
> +       if (!config->configured_msi)
> +               return -EINVAL;
> +
> +       if (vector >= config->configured_msi)
> +               return -EINVAL;
> +
> +       ven_msi = readl(&app_reg->ven_msi_1);
> +       ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
> +       ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
> +       ven_msi &= ~VEN_MSI_TC_MASK;
> +       ven_msi |= 0 << VEN_MSI_TC_ID;
> +       ven_msi &= ~VEN_MSI_VECTOR_MASK;
> +       ven_msi |= vector << VEN_MSI_VECTOR_ID;
> +
> +       /* generating interrupt for msi vector */
> +       ven_msi |= VEN_MSI_REQ_EN;
> +       writel(ven_msi, &app_reg->ven_msi_1);
> +       udelay(1);
> +       ven_msi &= ~VEN_MSI_REQ_EN;
> +       writel(ven_msi, &app_reg->ven_msi_1);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_vendor_id(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       u32 id;
> +
> +       spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
> +
> +       return sprintf(buf, "%x", id);
> +}
> +
> +static ssize_t pcie_gadget_store_vendor_id(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       ulong id;
> +
> +       if (strict_strtoul(buf, 0, &id))
> +               return -EINVAL;
> +
> +       spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_device_id(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       u32 id;
> +
> +       spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
> +
> +       return sprintf(buf, "%x", id);
> +}
> +
> +static ssize_t pcie_gadget_store_device_id(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       ulong id;
> +
> +       if (strict_strtoul(buf, 0, &id))
> +               return -EINVAL;
> +
> +       spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_size(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       return sprintf(buf, "%lx", config->bar0_size);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_size(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       ulong size;
> +       u32 pos, pos1;
> +       u32 no_of_bit = 0;
> +
> +       if (strict_strtoul(buf, 0, &size))
> +               return -EINVAL;
> +       /* min bar size is 256 */
> +       if (size <= 0x100)
> +               size = 0x100;
> +       /* max bar size is 1MB*/
> +       else if (size >= 0x100000)
> +               size = 0x100000;
> +       else {
> +               pos = 0;
> +               pos1 = 0;
> +               while (pos < 21) {
> +                       pos = find_next_bit((ulong *)&size, 21, pos);
> +                       if (pos != 21)
> +                               pos1 = pos + 1;
> +                       pos++;
> +                       no_of_bit++;
> +               }
> +               if (no_of_bit == 2)
> +                       pos1--;
> +
> +               size = 1 << pos1;
> +       }
> +       config->bar0_size = size;
> +       spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_address(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> +       u32 address = readl(&app_reg->pim0_mem_addr_start);
> +
> +       return sprintf(buf, "%x", address);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_address(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +       ulong address;
> +
> +       if (strict_strtoul(buf, 0, &address))
> +               return -EINVAL;
> +
> +       address &= ~(config->bar0_size - 1);
> +       if (config->va_bar0_address)
> +               iounmap(config->va_bar0_address);
> +       config->va_bar0_address = ioremap(address, config->bar0_size);
> +       if (!config->va_bar0_address)
> +               return -ENOMEM;
> +
> +       writel(address, &app_reg->pim0_mem_addr_start);
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_rw_offset(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       return sprintf(buf, "%lx", config->bar0_rw_offset);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_rw_offset(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       ulong offset;
> +
> +       if (strict_strtoul(buf, 0, &offset))
> +               return -EINVAL;
> +
> +       if (offset % 4)
> +               return -EINVAL;
> +
> +       config->bar0_rw_offset = offset;
> +
> +       return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_data(
> +               struct spear_pcie_gadget_config *config,
> +               char *buf)
> +{
> +       ulong data;
> +
> +       if (!config->va_bar0_address)
> +               return -ENOMEM;
> +
> +       data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset);
> +
> +       return sprintf(buf, "%lx", data);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_data(
> +               struct spear_pcie_gadget_config *config,
> +               const char *buf, size_t count)
> +{
> +       ulong data;
> +
> +       if (strict_strtoul(buf, 0, &data))
> +               return -EINVAL;
> +
> +       if (!config->va_bar0_address)
> +               return -ENOMEM;
> +
> +       writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset);
> +
> +       return count;
> +}
> +
> +/*
> + * Attribute definitions.
> + */
> +
> +#define PCIE_GADGET_TARGET_ATTR_RO(_name)                              \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
> +       __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
> +
> +#define PCIE_GADGET_TARGET_ATTR_WO(_name)                              \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
> +       __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
> +
> +#define PCIE_GADGET_TARGET_ATTR_RW(_name)                              \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name =     \
> +       __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
> +                       pcie_gadget_store_##_name)
> +PCIE_GADGET_TARGET_ATTR_RW(link);
> +PCIE_GADGET_TARGET_ATTR_RW(int_type);
> +PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
> +PCIE_GADGET_TARGET_ATTR_WO(inta);
> +PCIE_GADGET_TARGET_ATTR_WO(send_msi);
> +PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
> +PCIE_GADGET_TARGET_ATTR_RW(device_id);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
> +
> +static struct configfs_attribute *pcie_gadget_target_attrs[] = {
> +       &pcie_gadget_target_link.attr,
> +       &pcie_gadget_target_int_type.attr,
> +       &pcie_gadget_target_no_of_msi.attr,
> +       &pcie_gadget_target_inta.attr,
> +       &pcie_gadget_target_send_msi.attr,
> +       &pcie_gadget_target_vendor_id.attr,
> +       &pcie_gadget_target_device_id.attr,
> +       &pcie_gadget_target_bar0_size.attr,
> +       &pcie_gadget_target_bar0_address.attr,
> +       &pcie_gadget_target_bar0_rw_offset.attr,
> +       &pcie_gadget_target_bar0_data.attr,
> +       NULL,
> +};
> +
> +static struct pcie_gadget_target *to_target(struct config_item *item)
> +{
> +       return item ?
> +               container_of(to_configfs_subsystem(to_config_group(item)),
> +                               struct pcie_gadget_target, subsys) : NULL;
> +}
> +
> +/*
> + * Item operations and type for pcie_gadget_target.
> + */
> +
> +static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
> +                                          struct configfs_attribute *attr,
> +                                          char *buf)
> +{
> +       ssize_t ret = -EINVAL;
> +       struct pcie_gadget_target *target = to_target(item);
> +       struct pcie_gadget_target_attr *t_attr =
> +               container_of(attr, struct pcie_gadget_target_attr, attr);
> +
> +       if (t_attr->show)
> +               ret = t_attr->show(&target->config, buf);
> +       return ret;
> +}
> +
> +static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
> +                                       struct configfs_attribute *attr,
> +                                       const char *buf,
> +                                       size_t count)
> +{
> +       ssize_t ret = -EINVAL;
> +       struct pcie_gadget_target *target = to_target(item);
> +       struct pcie_gadget_target_attr *t_attr =
> +               container_of(attr, struct pcie_gadget_target_attr, attr);
> +
> +       if (t_attr->store)
> +               ret = t_attr->store(&target->config, buf, count);
> +       return ret;
> +}
> +
> +static struct configfs_item_operations pcie_gadget_target_item_ops = {
> +       .show_attribute         = pcie_gadget_target_attr_show,
> +       .store_attribute        = pcie_gadget_target_attr_store,
> +};
> +
> +static struct config_item_type pcie_gadget_target_type = {
> +       .ct_attrs               = pcie_gadget_target_attrs,
> +       .ct_item_ops            = &pcie_gadget_target_item_ops,
> +       .ct_owner               = THIS_MODULE,
> +};
> +
> +static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
> +{
> +       struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> +       /*setup registers for outbound translation */
> +
> +       writel(config->base, &app_reg->in0_mem_addr_start);
> +       writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
> +                       &app_reg->in0_mem_addr_limit);
> +       writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
> +       writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
> +                       &app_reg->in1_mem_addr_limit);
> +       writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
> +       writel(app_reg->in_io_addr_start + IN_IO_SIZE,
> +                       &app_reg->in_io_addr_limit);
> +       writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
> +       writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
> +                       &app_reg->in_cfg0_addr_limit);
> +       writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
> +       writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
> +                       &app_reg->in_cfg1_addr_limit);
> +       writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
> +       writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
> +                       &app_reg->in_msg_addr_limit);
> +
> +       writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
> +       writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
> +       writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
> +
> +       /*setup registers for inbound translation */
> +
> +       /* Keep AORAM mapped at BAR0 as default */
> +       config->bar0_size = INBOUND_ADDR_MASK + 1;
> +       spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
> +       spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
> +       config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE,
> +                       config->bar0_size);
> +
> +       writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
> +       writel(0, &app_reg->pim1_mem_addr_start);
> +       writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
> +
> +       writel(0x0, &app_reg->pim_io_addr_start);
> +       writel(0x0, &app_reg->pim_io_addr_start);
> +       writel(0x0, &app_reg->pim_rom_addr_start);
> +
> +       writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID)
> +                       | ((u32)1 << REG_TRANSLATION_ENABLE),
> +                       &app_reg->app_ctrl_0);
> +       /* disable all rx interrupts */
> +       writel(0, &app_reg->int_mask);
> +
> +       /* Select INTA as default*/
> +       spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
> +}
> +
> +static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
> +{
> +       struct resource *res0, *res1;
> +       unsigned int status = 0;
> +       int irq;
> +       struct clk *clk;
> +       static struct pcie_gadget_target *target;
> +       struct spear_pcie_gadget_config *config;
> +       struct config_item              *cg_item;
> +       struct configfs_subsystem *subsys;
> +
> +       /* get resource for application registers*/
> +
> +       res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res0) {
> +               dev_err(&pdev->dev, "no resource defined\n");
> +               return -EBUSY;
> +       }
> +       if (!request_mem_region(res0->start, resource_size(res0),
> +                               pdev->name)) {
> +               dev_err(&pdev->dev, "pcie gadget region already claimed\n");
> +               return -EBUSY;
> +       }
> +       /* get resource for dbi registers*/
> +
> +       res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +       if (!res1) {
> +               dev_err(&pdev->dev, "no resource defined\n");
> +               goto err_rel_res0;
> +       }
> +       if (!request_mem_region(res1->start, resource_size(res1),
> +                               pdev->name)) {
> +               dev_err(&pdev->dev, "pcie gadget region already claimed\n");
> +               goto err_rel_res0;
> +       }
> +
> +       target = kzalloc(sizeof(*target), GFP_KERNEL);
> +       if (!target) {
> +               dev_err(&pdev->dev, "out of memory\n");
> +               status = -ENOMEM;
> +               goto err_rel_res;
> +       }
> +
> +       cg_item = &target->subsys.su_group.cg_item;
> +       sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id);
> +       cg_item->ci_type        = &pcie_gadget_target_type;
> +       config = &target->config;
> +       config->va_app_base = (void __iomem *)ioremap(res0->start,
> +                       resource_size(res0));
> +       if (!config->va_app_base) {
> +               dev_err(&pdev->dev, "ioremap fail\n");
> +               status = -ENOMEM;
> +               goto err_kzalloc;
> +       }
> +
> +       config->base = (void __iomem *)res1->start;
> +
> +       config->va_dbi_base = (void __iomem *)ioremap(res1->start,
> +                       resource_size(res1));
> +       if (!config->va_dbi_base) {
> +               dev_err(&pdev->dev, "ioremap fail\n");
> +               status = -ENOMEM;
> +               goto err_iounmap_app;
> +       }
> +
> +       dev_set_drvdata(&pdev->dev, target);
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0) {
> +               dev_err(&pdev->dev, "no update irq?\n");
> +               status = irq;
> +               goto err_iounmap;
> +       }
> +
> +       status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
> +       if (status) {
> +               dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
> +                               claimed\n", irq);
> +               goto err_iounmap;
> +       }
> +
> +       /* Register configfs hooks */
> +       subsys = &target->subsys;
> +       config_group_init(&subsys->su_group);
> +       mutex_init(&subsys->su_mutex);
> +       status = configfs_register_subsystem(subsys);
> +       if (status)
> +               goto err_irq;
> +
> +       /*
> +        * init basic pcie application registers
> +        * do not enable clock if it is PCIE0.Ideally , all controller should
> +        * have been independent from others with respect to clock. But PCIE1
> +        * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
> +        */
> +       if (pdev->id == 1) {
> +               /*
> +                * Ideally CFG Clock should have been also enabled here. But
> +                * it is done currently during board init routne
> +                */
> +               clk = clk_get_sys("pcie1", NULL);
> +               if (IS_ERR(clk)) {
> +                       pr_err("%s:couldn't get clk for pcie1\n", __func__);
> +                       goto err_irq;
> +               }
> +               if (clk_enable(clk)) {
> +                       pr_err("%s:couldn't enable clk for pcie1\n", __func__);
> +                       goto err_irq;
> +               }
> +       } else if (pdev->id == 2) {
> +               /*
> +                * Ideally CFG Clock should have been also enabled here. But
> +                * it is done currently during board init routne
> +                */
> +               clk = clk_get_sys("pcie2", NULL);
> +               if (IS_ERR(clk)) {
> +                       pr_err("%s:couldn't get clk for pcie2\n", __func__);
> +                       goto err_irq;
> +               }
> +               if (clk_enable(clk)) {
> +                       pr_err("%s:couldn't enable clk for pcie2\n", __func__);
> +                       goto err_irq;
> +               }
> +       }
> +       spear13xx_pcie_device_init(config);
> +
> +       return 0;
> +err_irq:
> +       free_irq(irq, NULL);
> +err_iounmap:
> +       iounmap(config->va_dbi_base);
> +err_iounmap_app:
> +       iounmap(config->va_app_base);
> +err_kzalloc:
> +       kfree(config);
> +err_rel_res:
> +       release_mem_region(res1->start, resource_size(res1));
> +err_rel_res0:
> +       release_mem_region(res0->start, resource_size(res0));
> +       return status;
> +}
> +
> +static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
> +{
> +       struct resource *res0, *res1;
> +       static struct pcie_gadget_target *target;
> +       struct spear_pcie_gadget_config *config;
> +       int irq;
> +
> +       res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +       irq = platform_get_irq(pdev, 0);
> +       target = dev_get_drvdata(&pdev->dev);
> +       config = &target->config;
> +
> +       free_irq(irq, NULL);
> +       iounmap(config->va_dbi_base);
> +       iounmap(config->va_app_base);
> +       release_mem_region(res1->start, resource_size(res1));
> +       release_mem_region(res0->start, resource_size(res0));
> +       configfs_unregister_subsystem(&target->subsys);
> +       kfree(target);
> +
> +       return 0;
> +}
> +
> +static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
> +{
> +}
> +
> +static struct platform_driver spear_pcie_gadget_driver = {
> +       .probe = spear_pcie_gadget_probe,
> +       .remove = spear_pcie_gadget_remove,
> +       .shutdown = spear_pcie_gadget_shutdown,
> +       .driver = {
> +               .name = "pcie-gadget-spear",
> +               .bus = &platform_bus_type
> +       },
> +};
> +
> +static int __init spear_pcie_gadget_init(void)
> +{
> +       return platform_driver_register(&spear_pcie_gadget_driver);
> +}
> +module_init(spear_pcie_gadget_init);
> +
> +static void __exit spear_pcie_gadget_exit(void)
> +{
> +       platform_driver_unregister(&spear_pcie_gadget_driver);
> +}
> +module_exit(spear_pcie_gadget_exit);
> +
> +MODULE_ALIAS("pcie-gadget-spear");
> +MODULE_AUTHOR("Pratyush Anand");
> +MODULE_LICENSE("GPL");
> --
> 1.6.0.2
> 
> .
> 

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Hiroshi DOYU @ 2011-02-21  8:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297884951-3019-3-git-send-email-dacohen@gmail.com>

From: David Cohen <dacohen@gmail.com>
Subject: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
Date: Wed, 16 Feb 2011 21:35:51 +0200

> Add support to register an isr for IOMMU fault situations and adapt it
> to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
> module might want to be informed when errors happen in order to debug it
> or react.
> 
> Signed-off-by: David Cohen <dacohen@gmail.com>
> ---
>  arch/arm/mach-omap2/iommu2.c            |   17 +++++++++-
>  arch/arm/plat-omap/include/plat/iommu.h |   14 ++++++++-
>  arch/arm/plat-omap/iommu.c              |   52 ++++++++++++++++++++++---------
>  3 files changed, 65 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
> index 49a1e5e..adb083e 100644
> --- a/arch/arm/mach-omap2/iommu2.c
> +++ b/arch/arm/mach-omap2/iommu2.c
> @@ -146,18 +146,31 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
>  static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
>  {
>  	u32 stat, da;
> +	u32 errs = 0;
>  
>  	stat = iommu_read_reg(obj, MMU_IRQSTATUS);
>  	stat &= MMU_IRQ_MASK;
> -	if (!stat)
> +	if (!stat) {
> +		*ra = 0;
>  		return 0;
> +	}
>  
>  	da = iommu_read_reg(obj, MMU_FAULT_AD);
>  	*ra = da;
>  
> +	if (stat & MMU_IRQ_TLBMISS)
> +		errs |= OMAP_IOMMU_ERR_TLB_MISS;
> +	if (stat & MMU_IRQ_TRANSLATIONFAULT)
> +		errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
> +	if (stat & MMU_IRQ_EMUMISS)
> +		errs |= OMAP_IOMMU_ERR_EMU_MISS;
> +	if (stat & MMU_IRQ_TABLEWALKFAULT)
> +		errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
> +	if (stat & MMU_IRQ_MULTIHITFAULT)
> +		errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
>  	iommu_write_reg(obj, stat, MMU_IRQSTATUS);
>  
> -	return stat;
> +	return errs;
>  }
>  
>  static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
> diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
> index 19cbb5e..174f1b9 100644
> --- a/arch/arm/plat-omap/include/plat/iommu.h
> +++ b/arch/arm/plat-omap/include/plat/iommu.h
> @@ -31,6 +31,7 @@ struct iommu {
>  	struct clk	*clk;
>  	void __iomem	*regbase;
>  	struct device	*dev;
> +	void		*isr_priv;

Ideally I'd like to avoid having "isr_priv" in iommu since it's not
used for iommu but client needs the place to pass its info to its
custom handler. Any better idea?


>  	unsigned int	refcount;
>  	struct mutex	iommu_lock;	/* global for this whole object */
> @@ -47,7 +48,7 @@ struct iommu {
>  	struct list_head	mmap;
>  	struct mutex		mmap_lock; /* protect mmap */
>  
> -	int (*isr)(struct iommu *obj);
> +	int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv);
>  
>  	void *ctx; /* iommu context: registres saved area */
>  	u32 da_start;
> @@ -109,6 +110,13 @@ struct iommu_platform_data {
>  	u32 da_end;
>  };
>  
> +/* IOMMU errors */
> +#define OMAP_IOMMU_ERR_TLB_MISS		(1 << 0)
> +#define OMAP_IOMMU_ERR_TRANS_FAULT	(1 << 1)
> +#define OMAP_IOMMU_ERR_EMU_MISS		(1 << 2)
> +#define OMAP_IOMMU_ERR_TBLWALK_FAULT	(1 << 3)
> +#define OMAP_IOMMU_ERR_MULTIHIT_FAULT	(1 << 4)
> +
>  #if defined(CONFIG_ARCH_OMAP1)
>  #error "iommu for this processor not implemented yet"
>  #else
> @@ -161,6 +169,10 @@ extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
>  extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
>  extern struct iommu *iommu_get(const char *name);
>  extern void iommu_put(struct iommu *obj);
> +extern int iommu_set_isr(const char *name,
> +			 int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
> +				    void *priv),
> +			 void *isr_priv);
>  
>  extern void iommu_save_ctx(struct iommu *obj);
>  extern void iommu_restore_ctx(struct iommu *obj);
> diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
> index f55f458..b0e0efc 100644
> --- a/arch/arm/plat-omap/iommu.c
> +++ b/arch/arm/plat-omap/iommu.c
> @@ -780,25 +780,19 @@ static void iopgtable_clear_entry_all(struct iommu *obj)
>   */
>  static irqreturn_t iommu_fault_handler(int irq, void *data)
>  {
> -	u32 stat, da;
> +	u32 da, errs;
>  	u32 *iopgd, *iopte;
> -	int err = -EIO;
>  	struct iommu *obj = data;
>  
>  	if (!obj->refcount)
>  		return IRQ_NONE;
>  
> -	/* Dynamic loading TLB or PTE */
> -	if (obj->isr)
> -		err = obj->isr(obj);
> -
> -	if (!err)
> -		return IRQ_HANDLED;
> -
>  	clk_enable(obj->clk);
> -	stat = iommu_report_fault(obj, &da);
> +	errs = iommu_report_fault(obj, &da);
>  	clk_disable(obj->clk);
> -	if (!stat)
> +
> +	/* Fault callback or TLB/PTE Dynamic loading */
> +	if (obj->isr && !obj->isr(obj, da, errs, obj->isr_priv))
>  		return IRQ_HANDLED;
>  
>  	iommu_disable(obj);
> @@ -806,15 +800,16 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
>  	iopgd = iopgd_offset(obj, da);
>  
>  	if (!iopgd_is_table(*iopgd)) {
> -		dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", obj->name,
> -			da, iopgd, *iopgd);
> +		dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p "
> +			"*pgd:px%08x\n", obj->name, errs, da, iopgd, *iopgd);
>  		return IRQ_NONE;
>  	}
>  
>  	iopte = iopte_offset(iopgd, da);
>  
> -	dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
> -		obj->name, da, iopgd, *iopgd, iopte, *iopte);
> +	dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x "
> +		"pte:0x%p *pte:0x%08x\n", obj->name, errs, da, iopgd, *iopgd,
> +		iopte, *iopte);
>  
>  	return IRQ_NONE;
>  }
> @@ -917,6 +912,33 @@ void iommu_put(struct iommu *obj)
>  }
>  EXPORT_SYMBOL_GPL(iommu_put);
>  
> +int iommu_set_isr(const char *name,
> +		  int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
> +			     void *priv),
> +		  void *isr_priv)
> +{
> +	struct device *dev;
> +	struct iommu *obj;
> +
> +	dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
> +				 device_match_by_alias);
> +	if (!dev)
> +		return -ENODEV;
> +
> +	obj = to_iommu(dev);
> +	mutex_lock(&obj->iommu_lock);
> +	if (obj->refcount != 0) {
> +		mutex_unlock(&obj->iommu_lock);
> +		return -EBUSY;
> +	}
> +	obj->isr = isr;
> +	obj->isr_priv = isr_priv;
> +	mutex_unlock(&obj->iommu_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(iommu_set_isr);
> +
>  /*
>   *	OMAP Device MMU(IOMMU) detection
>   */
> -- 
> 1.7.2.3
> 

^ permalink raw reply

* [PATCH V5 Resend] ST SPEAr: PCIE gadget suppport
From: Pratyush Anand @ 2011-02-21  8:20 UTC (permalink / raw)
  To: linux-arm-kernel

This is a configurable gadget. can be configured by configfs interface. Any
IP available at PCIE bus can be programmed to be used by host
controller.It supoorts both INTX and MSI.
By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
with size 0x1000

Changes since V4:
- All documentation related comments incorporated

Changes since V3:
- support for multiple instances of such device
- changes to minimzie portability issue on 64 bit machine
- unnecessary typecast removed
- sysfs_streq used in place of complex code

Changes since V2:
- driver has been moved from sysfs to configfs
- Documentation/ABI directory has also been updated
- typo error in documenation has been corrected
- clk value is checked after encapsulating by IS_ERR

Changes since V1:
- __iomem added for register addresses
- kerneldoc comment removed whereever not required.
- help node moved from sysfs to documentation/misc-devices
- strict_strtoul used instead of sscanf

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
---
 .../ABI/testing/configfs-spear-pcie-gadget         |   30 +
 Documentation/misc-devices/spear-pcie-gadget.txt   |  129 +++
 drivers/misc/Kconfig                               |   10 +
 drivers/misc/Makefile                              |    1 +
 drivers/misc/spear13xx_pcie_gadget.c               |  908 ++++++++++++++++++++
 5 files changed, 1078 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-spear-pcie-gadget
 create mode 100644 Documentation/misc-devices/spear-pcie-gadget.txt
 create mode 100644 drivers/misc/spear13xx_pcie_gadget.c

diff --git a/Documentation/ABI/testing/configfs-spear-pcie-gadget b/Documentation/ABI/testing/configfs-spear-pcie-gadget
new file mode 100644
index 0000000..29593d0
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-spear-pcie-gadget
@@ -0,0 +1,30 @@
+What:		/config/pcie-gadget
+Date:		Feb 2011
+KernelVersion:	2.6.37
+Contact:	Pratyush Anand <pratyush.anand@st.com>
+Description:
+
+	Interface is used to configure selected dual mode PCIe controller
+	as device and then program its various registers to configure it
+	as a particular device type.
+	This interfaces can be used to show spear's PCIe device capability.
+
+	Nodes are only visible when configfs is mounted. To mount configfs
+	in /config directory use:
+	# mount -t configfs none /config/
+
+	/config/pcie-gadget/
+		link ... used to enable ltssm and read its status.
+		int_type ...used to configure and read type of supported
+			interrupt
+		no_of_msi ... used to configure number of MSI vector needed and
+			to read no of MSI granted.
+		inta ... write 1 to assert INTA and 0 to de-assert.
+		send_msi ... write MSI vector to be sent.
+		vendor_id ... used to write and read vendor id (hex)
+		device_id ... used to write and read device id (hex)
+		bar0_size ... used to write and read bar0_size
+		bar0_address ... used to write and read bar0 mapped area in hex.
+		bar0_rw_offset ... used to write and read offset of bar0 where
+			bar0_data will be written or read.
+		bar0_data ... used to write and read data at bar0_rw_offset.
diff --git a/Documentation/misc-devices/spear-pcie-gadget.txt b/Documentation/misc-devices/spear-pcie-gadget.txt
new file mode 100644
index 0000000..7b86b80
--- /dev/null
+++ b/Documentation/misc-devices/spear-pcie-gadget.txt
@@ -0,0 +1,129 @@
+Spear PCIe Gadget Driver:
+
+Author
+=============
+Pratyush Anand (pratyush.anand at st.com)
+
+Location
+============
+driver/misc/spear13xx_pcie_gadget.c
+
+Supported Chip:
+===================
+SPEAr1300
+SPEAr1310
+
+Menuconfig option:
+==========================
+Device Drivers
+	Misc devices
+		PCIe gadget support for SPEAr13XX platform
+purpose
+===========
+This driver has several nodes which can be read/written by configfs interface.
+Its main purpose is to configure selected dual mode PCIe controller as device
+and then program its various registers to configure it as a particular device
+type. This driver can be used to show spear's PCIe device capability.
+
+Description of different nodes:
+=================================
+
+read behavior of nodes:
+------------------------------
+link 		:gives ltssm status.
+int_type 	:type of supported interrupt
+no_of_msi 	:zero if MSI is not enabled by host. A positive value is the
+		number of MSI vector granted.
+vendor_id	:returns programmed vendor id (hex)
+device_id	:returns programmed device id(hex)
+bar0_size:	:returns size of bar0 in hex.
+bar0_address	:returns address of bar0 mapped area in hex.
+bar0_rw_offset	:returns offset of bar0 for which bar0_data will return value.
+bar0_data	:returns data at bar0_rw_offset.
+
+write behavior of nodes:
+------------------------------
+link 		:write UP to enable ltsmm DOWN to disable
+int_type	:write interrupt type to be configured and (int_type could be
+		INTA, MSI or NO_INT). Select MSI only when you have programmed
+		no_of_msi node.
+no_of_msi	:number of MSI vector needed.
+inta		:write 1 to assert INTA and 0 to de-assert.
+send_msi	:write MSI vector to be sent.
+vendor_id	:write vendor id(hex) to be programmed.
+device_id	:write device id(hex) to be programmed.
+bar0_size	:write size of bar0 in hex. default bar0 size is 1000 (hex)
+		bytes.
+bar0_address	:write	address of bar0 mapped area in hex. (default mapping of
+		bar0 is SYSRAM1(E0800000). Always program bar size before bar
+		address. Kernel might modify bar size and address for alignment, so
+		read back bar size and address after writing to cross check.
+bar0_rw_offset	:write offset of bar0 for which	bar0_data will write value.
+bar0_data	:write data to be written at bar0_rw_offset.
+
+Node programming example
+===========================
+Program all PCIe registers in such a way that when this device is connected
+to the PCIe host, then host sees this device as 1MB RAM.
+#mount -t configfs none /Config
+# cd /config/pcie_gadget/
+Now you have all the nodes in this directory.
+program vendor id as 0x104a
+# echo 104A >> vendor_id
+
+program device id as 0xCD80
+# echo CD80 >> device_id
+
+program BAR0 size as 1MB
+# echo 100000 >> bar0_size
+
+check for programmed bar0 size
+# cat bar0_size
+
+Program BAR0 Address as DDR (0x2100000). This is the physical address of
+memory, which is to be made visible to PCIe host. Similarly any other peripheral
+can also be made visible to PCIe host. E.g., if you program base address of UART
+as BAR0 address then when this device will be connected to a host, it will be
+visible as UART.
+# echo 2100000 >> bar0_address
+
+program interrupt type : INTA
+# echo INTA >> int_type
+
+go for link up now.
+# echo UP >> link
+
+It will have to be insured that, once link up is done on gadget, then only host
+is initialized and start to search PCIe devices on its port.
+
+/*wait till link is up*/
+# cat link
+wait till it returns UP.
+
+To assert INTA
+# echo 1 >> inta
+
+To de-assert INTA
+# echo 0 >> inta
+
+if MSI is to be used as interrupt, program no of msi vector needed (say4)
+# echo 4 >> no_of_msi
+
+select MSI as interrupt type
+# echo MSI >> int_type
+
+go for link up now
+# echo UP >> link
+
+wait till link is up
+# cat link
+An application can repetitively read this node till link is found UP. It can
+sleep between two read.
+
+wait till msi is enabled
+# cat no_of_msi
+Should return 4 (number of requested MSI vector)
+
+to send msi vector 2
+# echo 2 >> send_msi
+#cd -
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 4d073f1..dea052d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -394,6 +394,16 @@ config DS1682
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1682.
 
+config SPEAR13XX_PCIE_GADGET
+	bool "PCIe gadget support for SPEAr13XX platform"
+	depends on ARCH_SPEAR13XX
+	default n
+	help
+	 This option enables gadget support for PCIe controller. If
+	 board file defines any controller as PCIe endpoint then a sysfs
+	 entry will be created for that controller. User can use these
+	 sysfs node to configure PCIe EP as per his requirements.
+
 config TI_DAC7512
 	tristate "Texas Instruments DAC7512"
 	depends on SPI && SYSFS
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 98009cc..c489536 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_HMC6352)		+= hmc6352.o
 obj-y				+= eeprom/
 obj-y				+= cb710/
+obj-$(CONFIG_SPEAR13XX_PCIE_GADGET)	+= spear13xx_pcie_gadget.o
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmw_balloon.o
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
 obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
new file mode 100644
index 0000000..ec3b8c9
--- /dev/null
+++ b/drivers/misc/spear13xx_pcie_gadget.c
@@ -0,0 +1,908 @@
+/*
+ * drivers/misc/spear13xx_pcie_gadget.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Pratyush Anand<pratyush.anand@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pci_regs.h>
+#include <linux/configfs.h>
+#include <mach/pcie.h>
+#include <mach/misc_regs.h>
+
+#define IN0_MEM_SIZE	(200 * 1024 * 1024 - 1)
+/* In current implementation address translation is done using IN0 only.
+ * So IN1 start address and IN0 end address has been kept same
+*/
+#define IN1_MEM_SIZE	(0 * 1024 * 1024 - 1)
+#define IN_IO_SIZE	(20 * 1024 * 1024 - 1)
+#define IN_CFG0_SIZE	(12 * 1024 * 1024 - 1)
+#define IN_CFG1_SIZE	(12 * 1024 * 1024 - 1)
+#define IN_MSG_SIZE	(12 * 1024 * 1024 - 1)
+/* Keep default BAR size as 4K*/
+/* AORAM would be mapped by default*/
+#define INBOUND_ADDR_MASK	(SPEAR13XX_SYSRAM1_SIZE - 1)
+
+#define INT_TYPE_NO_INT	0
+#define INT_TYPE_INTX	1
+#define INT_TYPE_MSI	2
+struct spear_pcie_gadget_config {
+	void __iomem *base;
+	void __iomem *va_app_base;
+	void __iomem *va_dbi_base;
+	char int_type[10];
+	ulong requested_msi;
+	ulong configured_msi;
+	ulong bar0_size;
+	ulong bar0_rw_offset;
+	void __iomem *va_bar0_address;
+};
+
+struct pcie_gadget_target {
+	struct configfs_subsystem subsys;
+	struct spear_pcie_gadget_config config;
+};
+
+struct pcie_gadget_target_attr {
+	struct configfs_attribute	attr;
+	ssize_t		(*show)(struct spear_pcie_gadget_config *config,
+						char *buf);
+	ssize_t		(*store)(struct spear_pcie_gadget_config *config,
+						 const char *buf,
+						 size_t count);
+};
+
+static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg)
+{
+	/* Enable DBI access */
+	writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_armisc);
+	writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_awmisc);
+
+}
+
+static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg)
+{
+	/* disable DBI access */
+	writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_armisc);
+	writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
+			&app_reg->slv_awmisc);
+
+}
+
+static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config,
+		int where, int size, u32 *val)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	ulong va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (ulong)config->va_dbi_base + (where & ~0x3);
+
+	*val = readl(va_address);
+
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	/* Disable DBI access */
+	disable_dbi_access(app_reg);
+}
+
+static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config,
+		int where, int size, u32 val)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	ulong va_address;
+
+	/* Enable DBI access */
+	enable_dbi_access(app_reg);
+
+	va_address = (ulong)config->va_dbi_base + (where & ~0x3);
+
+	if (size == 4)
+		writel(val, va_address);
+	else if (size == 2)
+		writew(val, va_address + (where & 2));
+	else if (size == 1)
+		writeb(val, va_address + (where & 3));
+
+	/* Disable DBI access */
+	disable_dbi_access(app_reg);
+}
+
+#define PCI_FIND_CAP_TTL	48
+
+static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
+		u32 pos, int cap, int *ttl)
+{
+	u32 id;
+
+	while ((*ttl)--) {
+		spear_dbi_read_reg(config, pos, 1, &pos);
+		if (pos < 0x40)
+			break;
+		pos &= ~3;
+		spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos += PCI_CAP_LIST_NEXT;
+	}
+	return 0;
+}
+
+static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
+			u32 pos, int cap)
+{
+	int ttl = PCI_FIND_CAP_TTL;
+
+	return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
+}
+
+static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
+				u8 hdr_type)
+{
+	u32 status;
+
+	spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
+	if (!(status & PCI_STATUS_CAP_LIST))
+		return 0;
+
+	switch (hdr_type) {
+	case PCI_HEADER_TYPE_NORMAL:
+	case PCI_HEADER_TYPE_BRIDGE:
+		return PCI_CAPABILITY_LIST;
+	case PCI_HEADER_TYPE_CARDBUS:
+		return PCI_CB_CAPABILITY_LIST;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Tell if a device supports a given PCI capability.
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it. Possible values for @cap:
+ *
+ * %PCI_CAP_ID_PM	Power Management
+ * %PCI_CAP_ID_AGP	Accelerated Graphics Port
+ * %PCI_CAP_ID_VPD	Vital Product Data
+ * %PCI_CAP_ID_SLOTID	Slot Identification
+ * %PCI_CAP_ID_MSI	Message Signalled Interrupts
+ * %PCI_CAP_ID_CHSWP	CompactPCI HotSwap
+ * %PCI_CAP_ID_PCIX	PCI-X
+ * %PCI_CAP_ID_EXP	PCI Express
+ */
+static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
+		int cap)
+{
+	u32 pos;
+	u32 hdr_type;
+
+	spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
+
+	pos = pci_find_own_cap_start(config, hdr_type);
+	if (pos)
+		pos = pci_find_own_next_cap(config, pos, cap);
+
+	return pos;
+}
+
+static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
+{
+	return 0;
+}
+
+/*
+ * configfs interfaces show/store functions
+ */
+static ssize_t pcie_gadget_show_link(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+
+	if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
+		return sprintf(buf, "UP");
+	else
+		return sprintf(buf, "DOWN");
+}
+
+static ssize_t pcie_gadget_store_link(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+
+	if (sysfs_streq(buf, "UP"))
+		writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
+			&app_reg->app_ctrl_0);
+	else if (sysfs_streq(buf, "DOWN"))
+		writel(readl(&app_reg->app_ctrl_0)
+				& ~(1 << APP_LTSSM_ENABLE_ID),
+				&app_reg->app_ctrl_0);
+	else
+		return -EINVAL;
+	return count;
+}
+
+static ssize_t pcie_gadget_show_int_type(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	return sprintf(buf, "%s", config->int_type);
+}
+
+static ssize_t pcie_gadget_store_int_type(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	u32 cap, vec, flags;
+	ulong vector;
+
+	if (sysfs_streq(buf, "INTA"))
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+
+	else if (sysfs_streq(buf, "MSI")) {
+		vector = config->requested_msi;
+		vec = 0;
+		while (vector > 1) {
+			vector /= 2;
+			vec++;
+		}
+		spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QMASK;
+		flags |= vec << 1;
+		spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
+	} else
+		return -EINVAL;
+
+	strcpy(config->int_type, buf);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_no_of_msi(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	u32 cap, vec, flags;
+	ulong vector;
+
+	if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
+			!= (1 << CFG_MSI_EN_ID))
+		vector = 0;
+	else {
+		cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
+		spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
+		flags &= ~PCI_MSI_FLAGS_QSIZE;
+		vec = flags >> 4;
+		vector = 1;
+		while (vec--)
+			vector *= 2;
+	}
+	config->configured_msi = vector;
+
+	return sprintf(buf, "%lu", vector);
+}
+
+static ssize_t pcie_gadget_store_no_of_msi(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	if (strict_strtoul(buf, 0, &config->requested_msi))
+		return -EINVAL;
+	if (config->requested_msi > 32)
+		config->requested_msi = 32;
+
+	return count;
+}
+
+static ssize_t pcie_gadget_store_inta(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	ulong en;
+
+	if (strict_strtoul(buf, 0, &en))
+		return -EINVAL;
+
+	if (en)
+		writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+	else
+		writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
+				&app_reg->app_ctrl_0);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_store_send_msi(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	ulong vector;
+	u32 ven_msi;
+
+	if (strict_strtoul(buf, 0, &vector))
+		return -EINVAL;
+
+	if (!config->configured_msi)
+		return -EINVAL;
+
+	if (vector >= config->configured_msi)
+		return -EINVAL;
+
+	ven_msi = readl(&app_reg->ven_msi_1);
+	ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
+	ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
+	ven_msi &= ~VEN_MSI_TC_MASK;
+	ven_msi |= 0 << VEN_MSI_TC_ID;
+	ven_msi &= ~VEN_MSI_VECTOR_MASK;
+	ven_msi |= vector << VEN_MSI_VECTOR_ID;
+
+	/* generating interrupt for msi vector */
+	ven_msi |= VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+	udelay(1);
+	ven_msi &= ~VEN_MSI_REQ_EN;
+	writel(ven_msi, &app_reg->ven_msi_1);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_vendor_id(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_vendor_id(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	ulong id;
+
+	if (strict_strtoul(buf, 0, &id))
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_device_id(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	u32 id;
+
+	spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
+
+	return sprintf(buf, "%x", id);
+}
+
+static ssize_t pcie_gadget_store_device_id(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	ulong id;
+
+	if (strict_strtoul(buf, 0, &id))
+		return -EINVAL;
+
+	spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_bar0_size(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	return sprintf(buf, "%lx", config->bar0_size);
+}
+
+static ssize_t pcie_gadget_store_bar0_size(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	ulong size;
+	u32 pos, pos1;
+	u32 no_of_bit = 0;
+
+	if (strict_strtoul(buf, 0, &size))
+		return -EINVAL;
+	/* min bar size is 256 */
+	if (size <= 0x100)
+		size = 0x100;
+	/* max bar size is 1MB*/
+	else if (size >= 0x100000)
+		size = 0x100000;
+	else {
+		pos = 0;
+		pos1 = 0;
+		while (pos < 21) {
+			pos = find_next_bit((ulong *)&size, 21, pos);
+			if (pos != 21)
+				pos1 = pos + 1;
+			pos++;
+			no_of_bit++;
+		}
+		if (no_of_bit == 2)
+			pos1--;
+
+		size = 1 << pos1;
+	}
+	config->bar0_size = size;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_bar0_address(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+
+	u32 address = readl(&app_reg->pim0_mem_addr_start);
+
+	return sprintf(buf, "%x", address);
+}
+
+static ssize_t pcie_gadget_store_bar0_address(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+	ulong address;
+
+	if (strict_strtoul(buf, 0, &address))
+		return -EINVAL;
+
+	address &= ~(config->bar0_size - 1);
+	if (config->va_bar0_address)
+		iounmap(config->va_bar0_address);
+	config->va_bar0_address = ioremap(address, config->bar0_size);
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(address, &app_reg->pim0_mem_addr_start);
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_bar0_rw_offset(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	return sprintf(buf, "%lx", config->bar0_rw_offset);
+}
+
+static ssize_t pcie_gadget_store_bar0_rw_offset(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	ulong offset;
+
+	if (strict_strtoul(buf, 0, &offset))
+		return -EINVAL;
+
+	if (offset % 4)
+		return -EINVAL;
+
+	config->bar0_rw_offset = offset;
+
+	return count;
+}
+
+static ssize_t pcie_gadget_show_bar0_data(
+		struct spear_pcie_gadget_config *config,
+		char *buf)
+{
+	ulong data;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset);
+
+	return sprintf(buf, "%lx", data);
+}
+
+static ssize_t pcie_gadget_store_bar0_data(
+		struct spear_pcie_gadget_config *config,
+		const char *buf, size_t count)
+{
+	ulong data;
+
+	if (strict_strtoul(buf, 0, &data))
+		return -EINVAL;
+
+	if (!config->va_bar0_address)
+		return -ENOMEM;
+
+	writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset);
+
+	return count;
+}
+
+/*
+ * Attribute definitions.
+ */
+
+#define PCIE_GADGET_TARGET_ATTR_RO(_name)				\
+static struct pcie_gadget_target_attr pcie_gadget_target_##_name =	\
+	__CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
+
+#define PCIE_GADGET_TARGET_ATTR_WO(_name)				\
+static struct pcie_gadget_target_attr pcie_gadget_target_##_name =	\
+	__CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
+
+#define PCIE_GADGET_TARGET_ATTR_RW(_name)				\
+static struct pcie_gadget_target_attr pcie_gadget_target_##_name =	\
+	__CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
+			pcie_gadget_store_##_name)
+PCIE_GADGET_TARGET_ATTR_RW(link);
+PCIE_GADGET_TARGET_ATTR_RW(int_type);
+PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
+PCIE_GADGET_TARGET_ATTR_WO(inta);
+PCIE_GADGET_TARGET_ATTR_WO(send_msi);
+PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
+PCIE_GADGET_TARGET_ATTR_RW(device_id);
+PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
+PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
+PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
+PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
+
+static struct configfs_attribute *pcie_gadget_target_attrs[] = {
+	&pcie_gadget_target_link.attr,
+	&pcie_gadget_target_int_type.attr,
+	&pcie_gadget_target_no_of_msi.attr,
+	&pcie_gadget_target_inta.attr,
+	&pcie_gadget_target_send_msi.attr,
+	&pcie_gadget_target_vendor_id.attr,
+	&pcie_gadget_target_device_id.attr,
+	&pcie_gadget_target_bar0_size.attr,
+	&pcie_gadget_target_bar0_address.attr,
+	&pcie_gadget_target_bar0_rw_offset.attr,
+	&pcie_gadget_target_bar0_data.attr,
+	NULL,
+};
+
+static struct pcie_gadget_target *to_target(struct config_item *item)
+{
+	return item ?
+		container_of(to_configfs_subsystem(to_config_group(item)),
+				struct pcie_gadget_target, subsys) : NULL;
+}
+
+/*
+ * Item operations and type for pcie_gadget_target.
+ */
+
+static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
+					   struct configfs_attribute *attr,
+					   char *buf)
+{
+	ssize_t ret = -EINVAL;
+	struct pcie_gadget_target *target = to_target(item);
+	struct pcie_gadget_target_attr *t_attr =
+		container_of(attr, struct pcie_gadget_target_attr, attr);
+
+	if (t_attr->show)
+		ret = t_attr->show(&target->config, buf);
+	return ret;
+}
+
+static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
+					struct configfs_attribute *attr,
+					const char *buf,
+					size_t count)
+{
+	ssize_t ret = -EINVAL;
+	struct pcie_gadget_target *target = to_target(item);
+	struct pcie_gadget_target_attr *t_attr =
+		container_of(attr, struct pcie_gadget_target_attr, attr);
+
+	if (t_attr->store)
+		ret = t_attr->store(&target->config, buf, count);
+	return ret;
+}
+
+static struct configfs_item_operations pcie_gadget_target_item_ops = {
+	.show_attribute		= pcie_gadget_target_attr_show,
+	.store_attribute	= pcie_gadget_target_attr_store,
+};
+
+static struct config_item_type pcie_gadget_target_type = {
+	.ct_attrs		= pcie_gadget_target_attrs,
+	.ct_item_ops		= &pcie_gadget_target_item_ops,
+	.ct_owner		= THIS_MODULE,
+};
+
+static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
+{
+	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
+
+	/*setup registers for outbound translation */
+
+	writel(config->base, &app_reg->in0_mem_addr_start);
+	writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
+			&app_reg->in0_mem_addr_limit);
+	writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
+	writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
+			&app_reg->in1_mem_addr_limit);
+	writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
+	writel(app_reg->in_io_addr_start + IN_IO_SIZE,
+			&app_reg->in_io_addr_limit);
+	writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
+	writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
+			&app_reg->in_cfg0_addr_limit);
+	writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
+	writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
+			&app_reg->in_cfg1_addr_limit);
+	writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
+	writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
+			&app_reg->in_msg_addr_limit);
+
+	writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
+	writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
+	writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
+
+	/*setup registers for inbound translation */
+
+	/* Keep AORAM mapped at BAR0 as default */
+	config->bar0_size = INBOUND_ADDR_MASK + 1;
+	spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
+	spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
+	config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE,
+			config->bar0_size);
+
+	writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
+	writel(0, &app_reg->pim1_mem_addr_start);
+	writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
+
+	writel(0x0, &app_reg->pim_io_addr_start);
+	writel(0x0, &app_reg->pim_io_addr_start);
+	writel(0x0, &app_reg->pim_rom_addr_start);
+
+	writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID)
+			| ((u32)1 << REG_TRANSLATION_ENABLE),
+			&app_reg->app_ctrl_0);
+	/* disable all rx interrupts */
+	writel(0, &app_reg->int_mask);
+
+	/* Select INTA as default*/
+	spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
+}
+
+static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	unsigned int status = 0;
+	int irq;
+	struct clk *clk;
+	static struct pcie_gadget_target *target;
+	struct spear_pcie_gadget_config *config;
+	struct config_item		*cg_item;
+	struct configfs_subsystem *subsys;
+
+	/* get resource for application registers*/
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res0) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		return -EBUSY;
+	}
+	if (!request_mem_region(res0->start, resource_size(res0),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		return -EBUSY;
+	}
+	/* get resource for dbi registers*/
+
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res1) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		goto err_rel_res0;
+	}
+	if (!request_mem_region(res1->start, resource_size(res1),
+				pdev->name)) {
+		dev_err(&pdev->dev, "pcie gadget region already	claimed\n");
+		goto err_rel_res0;
+	}
+
+	target = kzalloc(sizeof(*target), GFP_KERNEL);
+	if (!target) {
+		dev_err(&pdev->dev, "out of memory\n");
+		status = -ENOMEM;
+		goto err_rel_res;
+	}
+
+	cg_item = &target->subsys.su_group.cg_item;
+	sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id);
+	cg_item->ci_type	= &pcie_gadget_target_type;
+	config = &target->config;
+	config->va_app_base = (void __iomem *)ioremap(res0->start,
+			resource_size(res0));
+	if (!config->va_app_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_kzalloc;
+	}
+
+	config->base = (void __iomem *)res1->start;
+
+	config->va_dbi_base = (void __iomem *)ioremap(res1->start,
+			resource_size(res1));
+	if (!config->va_dbi_base) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_iounmap_app;
+	}
+
+	dev_set_drvdata(&pdev->dev, target);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no update irq?\n");
+		status = irq;
+		goto err_iounmap;
+	}
+
+	status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
+	if (status) {
+		dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
+				claimed\n", irq);
+		goto err_iounmap;
+	}
+
+	/* Register configfs hooks */
+	subsys = &target->subsys;
+	config_group_init(&subsys->su_group);
+	mutex_init(&subsys->su_mutex);
+	status = configfs_register_subsystem(subsys);
+	if (status)
+		goto err_irq;
+
+	/*
+	 * init basic pcie application registers
+	 * do not enable clock if it is PCIE0.Ideally , all controller should
+	 * have been independent from others with respect to clock. But PCIE1
+	 * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
+	 */
+	if (pdev->id == 1) {
+		/*
+		 * Ideally CFG Clock should have been also enabled here. But
+		 * it is done currently during board init routne
+		 */
+		clk = clk_get_sys("pcie1", NULL);
+		if (IS_ERR(clk)) {
+			pr_err("%s:couldn't get clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie1\n", __func__);
+			goto err_irq;
+		}
+	} else if (pdev->id == 2) {
+		/*
+		 * Ideally CFG Clock should have been also enabled here. But
+		 * it is done currently during board init routne
+		 */
+		clk = clk_get_sys("pcie2", NULL);
+		if (IS_ERR(clk)) {
+			pr_err("%s:couldn't get clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+		if (clk_enable(clk)) {
+			pr_err("%s:couldn't enable clk for pcie2\n", __func__);
+			goto err_irq;
+		}
+	}
+	spear13xx_pcie_device_init(config);
+
+	return 0;
+err_irq:
+	free_irq(irq, NULL);
+err_iounmap:
+	iounmap(config->va_dbi_base);
+err_iounmap_app:
+	iounmap(config->va_app_base);
+err_kzalloc:
+	kfree(config);
+err_rel_res:
+	release_mem_region(res1->start, resource_size(res1));
+err_rel_res0:
+	release_mem_region(res0->start, resource_size(res0));
+	return status;
+}
+
+static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
+{
+	struct resource *res0, *res1;
+	static struct pcie_gadget_target *target;
+	struct spear_pcie_gadget_config *config;
+	int irq;
+
+	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	irq = platform_get_irq(pdev, 0);
+	target = dev_get_drvdata(&pdev->dev);
+	config = &target->config;
+
+	free_irq(irq, NULL);
+	iounmap(config->va_dbi_base);
+	iounmap(config->va_app_base);
+	release_mem_region(res1->start, resource_size(res1));
+	release_mem_region(res0->start, resource_size(res0));
+	configfs_unregister_subsystem(&target->subsys);
+	kfree(target);
+
+	return 0;
+}
+
+static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
+{
+}
+
+static struct platform_driver spear_pcie_gadget_driver = {
+	.probe = spear_pcie_gadget_probe,
+	.remove = spear_pcie_gadget_remove,
+	.shutdown = spear_pcie_gadget_shutdown,
+	.driver = {
+		.name = "pcie-gadget-spear",
+		.bus = &platform_bus_type
+	},
+};
+
+static int __init spear_pcie_gadget_init(void)
+{
+	return platform_driver_register(&spear_pcie_gadget_driver);
+}
+module_init(spear_pcie_gadget_init);
+
+static void __exit spear_pcie_gadget_exit(void)
+{
+	platform_driver_unregister(&spear_pcie_gadget_driver);
+}
+module_exit(spear_pcie_gadget_exit);
+
+MODULE_ALIAS("pcie-gadget-spear");
+MODULE_AUTHOR("Pratyush Anand");
+MODULE_LICENSE("GPL");
-- 
1.6.0.2

^ permalink raw reply related

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Felipe Balbi @ 2011-02-21  8:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110221.101856.76372714451194378.Hiroshi.DOYU@nokia.com>

Hi,

On Mon, Feb 21, 2011 at 10:18:56AM +0200, Hiroshi DOYU wrote:
> From: David Cohen <dacohen@gmail.com>
> Subject: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
> Date: Wed, 16 Feb 2011 21:35:51 +0200
> 
> > Add support to register an isr for IOMMU fault situations and adapt it
> > to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
> > module might want to be informed when errors happen in order to debug it
> > or react.
> > 
> > Signed-off-by: David Cohen <dacohen@gmail.com>
> > ---
> >  arch/arm/mach-omap2/iommu2.c            |   17 +++++++++-
> >  arch/arm/plat-omap/include/plat/iommu.h |   14 ++++++++-
> >  arch/arm/plat-omap/iommu.c              |   52 ++++++++++++++++++++++---------
> >  3 files changed, 65 insertions(+), 18 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
> > index 49a1e5e..adb083e 100644
> > --- a/arch/arm/mach-omap2/iommu2.c
> > +++ b/arch/arm/mach-omap2/iommu2.c
> > @@ -146,18 +146,31 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
> >  static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
> >  {
> >  	u32 stat, da;
> > +	u32 errs = 0;
> >  
> >  	stat = iommu_read_reg(obj, MMU_IRQSTATUS);
> >  	stat &= MMU_IRQ_MASK;
> > -	if (!stat)
> > +	if (!stat) {
> > +		*ra = 0;
> >  		return 0;
> > +	}
> >  
> >  	da = iommu_read_reg(obj, MMU_FAULT_AD);
> >  	*ra = da;
> >  
> > +	if (stat & MMU_IRQ_TLBMISS)
> > +		errs |= OMAP_IOMMU_ERR_TLB_MISS;
> > +	if (stat & MMU_IRQ_TRANSLATIONFAULT)
> > +		errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
> > +	if (stat & MMU_IRQ_EMUMISS)
> > +		errs |= OMAP_IOMMU_ERR_EMU_MISS;
> > +	if (stat & MMU_IRQ_TABLEWALKFAULT)
> > +		errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
> > +	if (stat & MMU_IRQ_MULTIHITFAULT)
> > +		errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
> >  	iommu_write_reg(obj, stat, MMU_IRQSTATUS);
> >  
> > -	return stat;
> > +	return errs;
> >  }
> >  
> >  static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
> > diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
> > index 19cbb5e..174f1b9 100644
> > --- a/arch/arm/plat-omap/include/plat/iommu.h
> > +++ b/arch/arm/plat-omap/include/plat/iommu.h
> > @@ -31,6 +31,7 @@ struct iommu {
> >  	struct clk	*clk;
> >  	void __iomem	*regbase;
> >  	struct device	*dev;
> > +	void		*isr_priv;
> 
> Ideally I'd like to avoid having "isr_priv" in iommu since it's not
> used for iommu but client needs the place to pass its info to its
> custom handler. Any better idea?

I'm not sure if it makes sense as I don't know the mailbox block, but
maybe moving to GENIRQ ? Then IRQ subsystem would take care of the
"dev_id"

-- 
balbi

^ permalink raw reply

* [PATCH v5 4/5] ARM: omap3: Thumb-2 compatibility for sram34xx.S
From: Jean Pihet @ 2011-02-21  8:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297946558-13436-5-git-send-email-dave.martin@linaro.org>

On Thu, Feb 17, 2011 at 1:42 PM, Dave Martin <dave.martin@linaro.org> wrote:
> ?* Build unconditionally as ARM for correct interoperation with
> ? OMAP firmware.
>
> ?* Remove deprecated PC-relative stores
>
> ?* Add the required ENDPROC() directive for each ENTRY().
>
> ?* .align before data words
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
> ---
> ?arch/arm/mach-omap2/sram34xx.S | ? 36 ++++++++++++++++++++++++++++--------
> ?1 files changed, 28 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
> index 7f893a2..fd1531c 100644
> --- a/arch/arm/mach-omap2/sram34xx.S
> +++ b/arch/arm/mach-omap2/sram34xx.S
> @@ -34,6 +34,12 @@
> ?#include "sdrc.h"
> ?#include "cm2xxx_3xxx.h"
>
> +/*
> + * This file needs be built unconditionally as ARM to interoperate correctly
> + * with non-Thumb-2-capable firmware.
> + */
> + ? ? ? .arm
> +
> ? ? ? ?.text
>
> ?/* r1 parameters */
> @@ -116,24 +122,36 @@ ENTRY(omap3_sram_configure_core_dpll)
>
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@ pull the extra args off the stack
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@ ?and store them in SRAM
> +
> +/*
> + * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour
> + * in Thumb-2: use a r7 as a base instead.
> + * Be careful not to clobber r7 when maintaing this file.
Sorry I forgot about this minor typo: 'maintaining'

Jean

> + */
> + THUMB( ? ? ? ?adr ? ? r7, omap3_sram_configure_core_dpll ? ? ? ? ? ? ? ? ? ? ?)
> + ? ? ? .macro strtext Rt:req, label:req
> + ARM( ?str ? ? \Rt, \label ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )
> + THUMB( ? ? ? ?str ? ? \Rt, [r7, \label - omap3_sram_configure_core_dpll] ? ? ?)
> + ? ? ? .endm
> +
> ? ? ? ?ldr ? ? r4, [sp, #52]
> - ? ? ? str ? ? r4, omap_sdrc_rfr_ctrl_0_val
> + ? ? ? strtext r4, omap_sdrc_rfr_ctrl_0_val
> ? ? ? ?ldr ? ? r4, [sp, #56]
> - ? ? ? str ? ? r4, omap_sdrc_actim_ctrl_a_0_val
> + ? ? ? strtext r4, omap_sdrc_actim_ctrl_a_0_val
> ? ? ? ?ldr ? ? r4, [sp, #60]
> - ? ? ? str ? ? r4, omap_sdrc_actim_ctrl_b_0_val
> + ? ? ? strtext r4, omap_sdrc_actim_ctrl_b_0_val
> ? ? ? ?ldr ? ? r4, [sp, #64]
> - ? ? ? str ? ? r4, omap_sdrc_mr_0_val
> + ? ? ? strtext r4, omap_sdrc_mr_0_val
> ? ? ? ?ldr ? ? r4, [sp, #68]
> - ? ? ? str ? ? r4, omap_sdrc_rfr_ctrl_1_val
> + ? ? ? strtext r4, omap_sdrc_rfr_ctrl_1_val
> ? ? ? ?cmp ? ? r4, #0 ? ? ? ? ? ? ? ? ?@ if SDRC_RFR_CTRL_1 is 0,
> ? ? ? ?beq ? ? skip_cs1_params ? ? ? ? @ ?do not use cs1 params
> ? ? ? ?ldr ? ? r4, [sp, #72]
> - ? ? ? str ? ? r4, omap_sdrc_actim_ctrl_a_1_val
> + ? ? ? strtext r4, omap_sdrc_actim_ctrl_a_1_val
> ? ? ? ?ldr ? ? r4, [sp, #76]
> - ? ? ? str ? ? r4, omap_sdrc_actim_ctrl_b_1_val
> + ? ? ? strtext r4, omap_sdrc_actim_ctrl_b_1_val
> ? ? ? ?ldr ? ? r4, [sp, #80]
> - ? ? ? str ? ? r4, omap_sdrc_mr_1_val
> + ? ? ? strtext r4, omap_sdrc_mr_1_val
> ?skip_cs1_params:
> ? ? ? ?mrc ? ? p15, 0, r8, c1, c0, 0 ? @ read ctrl register
> ? ? ? ?bic ? ? r10, r8, #0x800 ? ? ? ? @ clear Z-bit, disable branch prediction
> @@ -271,6 +289,7 @@ skip_cs1_prog:
> ? ? ? ?ldr ? ? r12, [r11] ? ? ? ? ? ? ?@ posted-write barrier for SDRC
> ? ? ? ?bx ? ? ?lr
>
> + ? ? ? .align
> ?omap3_sdrc_power:
> ? ? ? ?.word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
> ?omap3_cm_clksel1_pll:
> @@ -319,6 +338,7 @@ omap3_sdrc_dlla_ctrl:
> ? ? ? ?.word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
> ?core_m2_mask_val:
> ? ? ? ?.word 0x07FFFFFF
> +ENDPROC(omap3_sram_configure_core_dpll)
>
> ?ENTRY(omap3_sram_configure_core_dpll_sz)
> ? ? ? ?.word ? . - omap3_sram_configure_core_dpll
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH V4 3/4] ARM: Xilinx: base header files and assembly macros
From: Arnd Bergmann @ 2011-02-21  8:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c170bbf2-ac0a-4c55-b2a7-0215c7a79635@VA3EHSMHS032.ehs.local>

On Monday 21 February 2011, John Linn wrote:
> > > diff --git a/arch/arm/mach-xilinx/include/mach/timex.h
> > b/arch/arm/mach-xilinx/include/mach/timex.h
> > > new file mode 100644
> > > index 0000000..4ebc0a6
> > > --- /dev/null
> > > +++ b/arch/arm/mach-xilinx/include/mach/timex.h
> > > +#ifndef __MACH_TIMEX_H__
> > > +#define __MACH_TIMEX_H__
> > > +
> > > +#define PERIPHERAL_CLOCK_RATE  2500000
> > > +
> > > +#define CLOCK_TICK_RATE        (PERIPHERAL_CLOCK_RATE / 32)
> > > +
> > > +#endif
> > 
> > I thought we were at the point where CLOCK_TICK_RATE is no longer
> used.
> 
> The timer code in these patches is using it, no other comments on it so
> far.
> 
> > Did the patches not make it in yet?
> > 
> 
> I haven't heard they made them in yet, just waiting and hoping for an
> ack.

I meant the patches removing CLOCK_TICK_RATE from common code, not your
patches, sorry for being vague.

It would be better if you could avoid introducing new uses of
CLOCK_TICK_RATE, because that will have to be removed before we can 
move to a real multi-platform kernel. For instance, you can put
PERIPHERAL_CLOCK_RATE in a hardware specific header and put a bogus
definition for CLOCK_TICK_RATE into timex.h

	Arnd

^ permalink raw reply

* [PATCH 2/4] V4L: mx3_camera: convert to videobuf2
From: Guennadi Liakhovetski @ 2011-02-21  8:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <000001cbd19e$1f528210$5df78630$%szyprowski@samsung.com>

Hi Marek

Thanks for your review, I'll update the patch accordingly.

Regards
Guennadi

On Mon, 21 Feb 2011, Marek Szyprowski wrote:

> Hello,
> 
> On Friday, February 18, 2011 9:14 AM Guennadi Liakhovetski wrote:
> 
> > Now that soc-camera supports videobuf API v1 and v2, camera-host drivers
> > can be converted to videobuf2 individually. This patch converts the
> > mx3_camera driver.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---
> > 
> > This one is also on git.linuxtv.org already.
> > 
> >  drivers/media/video/mx3_camera.c |  342 ++++++++++++++++----------------------
> >  1 files changed, 143 insertions(+), 199 deletions(-)
> > 
> > diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
> > index b9cb4a4..d61ff0d 100644
> > --- a/drivers/media/video/mx3_camera.c
> > +++ b/drivers/media/video/mx3_camera.c
> > @@ -21,7 +21,7 @@
> > 
> >  #include <media/v4l2-common.h>
> >  #include <media/v4l2-dev.h>
> > -#include <media/videobuf-dma-contig.h>
> > +#include <media/videobuf2-dma-contig.h>
> >  #include <media/soc_camera.h>
> >  #include <media/soc_mediabus.h>
> > 
> > @@ -62,10 +62,16 @@
> > 
> >  #define MAX_VIDEO_MEM 16
> > 
> > +enum csi_buffer_state {
> > +	CSI_BUF_NEEDS_INIT,
> > +	CSI_BUF_PREPARED,
> > +};
> > +
> >  struct mx3_camera_buffer {
> >  	/* common v4l buffer stuff -- must be first */
> > -	struct videobuf_buffer			vb;
> > -	enum v4l2_mbus_pixelcode		code;
> > +	struct vb2_buffer			vb;
> > +	enum csi_buffer_state			state;
> > +	struct list_head			queue;
> > 
> >  	/* One descriptot per scatterlist (per frame) */
> >  	struct dma_async_tx_descriptor		*txd;
> > @@ -108,6 +114,9 @@ struct mx3_camera_dev {
> >  	struct list_head	capture;
> >  	spinlock_t		lock;		/* Protects video buffer lists */
> >  	struct mx3_camera_buffer *active;
> > +	struct vb2_alloc_ctx	*alloc_ctx;
> > +	enum v4l2_field		field;
> > +	int			sequence;
> > 
> >  	/* IDMAC / dmaengine interface */
> >  	struct idmac_channel	*idmac_channel[1];	/* We need one channel */
> > @@ -130,6 +139,11 @@ static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
> >  	__raw_writel(value, mx3->base + reg);
> >  }
> > 
> > +static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
> > +{
> > +	return container_of(vb, struct mx3_camera_buffer, vb);
> > +}
> > +
> >  /* Called from the IPU IDMAC ISR */
> >  static void mx3_cam_dma_done(void *arg)
> >  {
> > @@ -137,20 +151,20 @@ static void mx3_cam_dma_done(void *arg)
> >  	struct dma_chan *chan = desc->txd.chan;
> >  	struct idmac_channel *ichannel = to_idmac_chan(chan);
> >  	struct mx3_camera_dev *mx3_cam = ichannel->client;
> > -	struct videobuf_buffer *vb;
> > 
> >  	dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
> >  		desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
> > 
> >  	spin_lock(&mx3_cam->lock);
> >  	if (mx3_cam->active) {
> > -		vb = &mx3_cam->active->vb;
> > -
> > -		list_del_init(&vb->queue);
> > -		vb->state = VIDEOBUF_DONE;
> > -		do_gettimeofday(&vb->ts);
> > -		vb->field_count++;
> > -		wake_up(&vb->done);
> > +		struct vb2_buffer *vb = &mx3_cam->active->vb;
> > +		struct mx3_camera_buffer *buf = to_mx3_vb(vb);
> > +
> > +		list_del_init(&buf->queue);
> > +		do_gettimeofday(&vb->v4l2_buf.timestamp);
> > +		vb->v4l2_buf.field = mx3_cam->field;
> > +		vb->v4l2_buf.sequence = mx3_cam->sequence++;
> > +		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
> >  	}
> > 
> >  	if (list_empty(&mx3_cam->capture)) {
> > @@ -165,38 +179,10 @@ static void mx3_cam_dma_done(void *arg)
> >  	}
> > 
> >  	mx3_cam->active = list_entry(mx3_cam->capture.next,
> > -				     struct mx3_camera_buffer, vb.queue);
> > -	mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
> > +				     struct mx3_camera_buffer, queue);
> >  	spin_unlock(&mx3_cam->lock);
> >  }
> > 
> > -static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
> > -{
> > -	struct soc_camera_device *icd = vq->priv_data;
> > -	struct videobuf_buffer *vb = &buf->vb;
> > -	struct dma_async_tx_descriptor *txd = buf->txd;
> > -	struct idmac_channel *ichan;
> > -
> > -	BUG_ON(in_interrupt());
> > -
> > -	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
> > -		vb, vb->baddr, vb->bsize);
> > -
> > -	/*
> > -	 * This waits until this buffer is out of danger, i.e., until it is no
> > -	 * longer in STATE_QUEUED or STATE_ACTIVE
> > -	 */
> > -	videobuf_waiton(vq, vb, 0, 0);
> > -	if (txd) {
> > -		ichan = to_idmac_chan(txd->chan);
> > -		async_tx_ack(txd);
> > -	}
> > -	videobuf_dma_contig_free(vq, vb);
> > -	buf->txd = NULL;
> > -
> > -	vb->state = VIDEOBUF_NEEDS_INIT;
> > -}
> > -
> >  /*
> >   * Videobuf operations
> >   */
> > @@ -205,10 +191,11 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
> >   * Calculate the __buffer__ (not data) size and number of buffers.
> >   * Called with .vb_lock held
> >   */
> > -static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
> > -			      unsigned int *size)
> > +static int mx3_videobuf_setup(struct vb2_queue *vq,
> > +			unsigned int *count, unsigned int *num_planes,
> > +			unsigned long sizes[], void *alloc_ctxs[])
> >  {
> > -	struct soc_camera_device *icd = vq->priv_data;
> > +	struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
> >  	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
> >  	struct mx3_camera_dev *mx3_cam = ici->priv;
> >  	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
> > @@ -220,104 +207,68 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
> >  	if (!mx3_cam->idmac_channel[0])
> >  		return -EINVAL;
> > 
> > -	*size = bytes_per_line * icd->user_height;
> > +	*num_planes = 1;
> > +
> > +	mx3_cam->sequence = 0;
> > +	sizes[0] = bytes_per_line * icd->user_height;
> > +	alloc_ctxs[0] = mx3_cam->alloc_ctx;
> > 
> >  	if (!*count)
> >  		*count = 32;
> > 
> > -	if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
> > -		*count = MAX_VIDEO_MEM * 1024 * 1024 / *size;
> > +	if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
> > +		*count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
> > 
> >  	return 0;
> >  }
> > 
> >  /* Called with .vb_lock held */
> 
> vb_lock has no meaning in vb2, so the above line should be removed imho.
> 
> > -static int mx3_videobuf_prepare(struct videobuf_queue *vq,
> > -		struct videobuf_buffer *vb, enum v4l2_field field)
> > +static int mx3_videobuf_prepare(struct vb2_buffer *vb)
> >  {
> > -	struct soc_camera_device *icd = vq->priv_data;
> > +	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
> >  	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
> >  	struct mx3_camera_dev *mx3_cam = ici->priv;
> > -	struct mx3_camera_buffer *buf =
> > -		container_of(vb, struct mx3_camera_buffer, vb);
> > +	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
> > +	struct scatterlist *sg;
> > +	struct mx3_camera_buffer *buf;
> >  	size_t new_size;
> > -	int ret;
> >  	int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
> >  						icd->current_fmt->host_fmt);
> > 
> >  	if (bytes_per_line < 0)
> >  		return bytes_per_line;
> > 
> > -	new_size = bytes_per_line * icd->user_height;
> > +	buf = to_mx3_vb(vb);
> > +	sg = &buf->sg;
> > 
> > -	/*
> > -	 * I think, in buf_prepare you only have to protect global data,
> > -	 * the actual buffer is yours
> > -	 */
> > -
> > -	if (buf->code	!= icd->current_fmt->code ||
> > -	    vb->width	!= icd->user_width ||
> > -	    vb->height	!= icd->user_height ||
> > -	    vb->field	!= field) {
> > -		buf->code	= icd->current_fmt->code;
> > -		vb->width	= icd->user_width;
> > -		vb->height	= icd->user_height;
> > -		vb->field	= field;
> > -		if (vb->state != VIDEOBUF_NEEDS_INIT)
> > -			free_buffer(vq, buf);
> > -	}
> > +	new_size = bytes_per_line * icd->user_height;
> > 
> > -	if (vb->baddr && vb->bsize < new_size) {
> > -		/* User provided buffer, but it is too small */
> > -		ret = -ENOMEM;
> > -		goto out;
> > +	if (vb2_plane_size(vb, 0) < new_size) {
> > +		dev_err(icd->dev.parent, "Buffer too small (%lu < %zu)\n",
> > +			vb2_plane_size(vb, 0), new_size);
> > +		return -ENOBUFS;
> >  	}
> > 
> > -	if (vb->state == VIDEOBUF_NEEDS_INIT) {
> > -		struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
> > -		struct scatterlist *sg = &buf->sg;
> > -
> > -		/*
> > -		 * The total size of video-buffers that will be allocated / mapped.
> > -		 * *size that we calculated in videobuf_setup gets assigned to
> > -		 * vb->bsize, and now we use the same calculation to get vb->size.
> > -		 */
> > -		vb->size = new_size;
> > -
> > -		/* This actually (allocates and) maps buffers */
> > -		ret = videobuf_iolock(vq, vb, NULL);
> > -		if (ret)
> > -			goto fail;
> > -
> > -		/*
> > -		 * We will have to configure the IDMAC channel. It has two slots
> > -		 * for DMA buffers, we shall enter the first two buffers there,
> > -		 * and then submit new buffers in DMA-ready interrupts
> > -		 */
> > -		sg_init_table(sg, 1);
> > -		sg_dma_address(sg)	= videobuf_to_dma_contig(vb);
> > -		sg_dma_len(sg)		= vb->size;
> > +	if (buf->state == CSI_BUF_NEEDS_INIT) {
> > +		sg_dma_address(sg)	= (dma_addr_t)icd->vb2_vidq.mem_ops->cookie(
> > +			vb->planes[0].mem_priv);
> 
> You should use vb2_dma_contig_plane_paddr() function from include/media/videobuf2-dma-contig.h
> instead of hacking with cookie directly:
> 	sg_dma_address(sg) = vb2_dma_contig_plane_paddr(vb, 0);
> 
> Everything else look fine!
> 
> > [snip]
> 
> Best regards
> --
> Marek Szyprowski
> Samsung Poland R&D Center
> 
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH] perf: add OMAP support for the new power events
From: Jean Pihet @ 2011-02-21  8:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ec45f3f591691ce6a5253dfb70cc8e90@mail.gmail.com>

Hi Santosh,

On Sat, Feb 19, 2011 at 7:55 PM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:
>> -----Original Message-----
>> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
>> owner at vger.kernel.org] On Behalf Of jean.pihet at newoldbits.com
>> Sent: Friday, February 18, 2011 11:41 PM
>> To: Kevin Hilman; Thomas Renninger; linux-omap at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org
>> Cc: Jean Pihet
>> Subject: [PATCH] perf: add OMAP support for the new power events
>>
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> The patch adds the new power management trace points for
>> the OMAP architecture.
>>
>> The trace points are for:
>> - default idle handler. Since the cpuidle framework is
>> ? instrumented in the generic way there is no need to
>> ? add trace points in the OMAP specific cpuidle handler;
>> - cpufreq (DVFS),
>> - SoC clocks changes (enable, disable, set_rate),
>> - power domain states: the desired target state and -if different-
>> ? the actually hit state.
>>
>> Because of the generic nature of the changes, OMAP3 and OMAP4 are
>> supported.
>>
>> Tested on OMAP3 with suspend/resume, cpuidle, basic DVFS.
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>> ---
>> ?arch/arm/mach-omap2/clock.c ? ? ? | ? ?8 +++++++-
>> ?arch/arm/mach-omap2/pm34xx.c ? ? ?| ? ?7 +++++++
>> ?arch/arm/mach-omap2/powerdomain.c | ? 26 +++++++++++++++++++++++---
>> ?3 files changed, 37 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-
>> omap2/clock.c
>> index 2a2f152..72af75d 100644
>> --- a/arch/arm/mach-omap2/clock.c
>> +++ b/arch/arm/mach-omap2/clock.c
>> @@ -22,7 +22,9 @@
>> ?#include <linux/clk.h>
>> ?#include <linux/io.h>
>> ?#include <linux/bitops.h>
>> +#include <trace/events/power.h>
>>
>> +#include <asm/cpu.h>
>> ?#include <plat/clock.h>
>> ?#include "clockdomain.h"
>> ?#include <plat/cpu.h>
>> @@ -261,6 +263,7 @@ void omap2_clk_disable(struct clk *clk)
>>
>> ? ? ? pr_debug("clock: %s: disabling in hardware\n", clk->name);
>>
>> + ? ? trace_clock_disable(clk->name, 0, smp_processor_id());
>> ? ? ? clk->ops->disable(clk);
>>
>> ? ? ? if (clk->clkdm)
>> @@ -312,6 +315,7 @@ int omap2_clk_enable(struct clk *clk)
>> ? ? ? ? ? ? ? }
>> ? ? ? }
>>
>> + ? ? trace_clock_enable(clk->name, 1, smp_processor_id());
>> ? ? ? ret = clk->ops->enable(clk);
>> ? ? ? if (ret) {
>> ? ? ? ? ? ? ? WARN(1, "clock: %s: could not enable: %d\n", clk->name,
>> ret);
>> @@ -349,8 +353,10 @@ int omap2_clk_set_rate(struct clk *clk,
>> unsigned long rate)
>> ? ? ? pr_debug("clock: set_rate for clock %s to rate %ld\n", clk-
>> >name, rate);
>>
>> ? ? ? /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
>> - ? ? if (clk->set_rate)
>> + ? ? if (clk->set_rate) {
>> + ? ? ? ? ? ? trace_clock_set_rate(clk->name, rate,
>> smp_processor_id());
>> ? ? ? ? ? ? ? ret = clk->set_rate(clk, rate);
>> + ? ? }
>>
>> ? ? ? return ret;
>> ?}
>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-
>> omap2/pm34xx.c
>> index 2f864e4..d1cc3f4 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -29,6 +29,7 @@
>> ?#include <linux/delay.h>
>> ?#include <linux/slab.h>
>> ?#include <linux/console.h>
>> +#include <trace/events/power.h>
>>
>> ?#include <plat/sram.h>
>> ?#include "clockdomain.h"
>> @@ -519,8 +520,14 @@ static void omap3_pm_idle(void)
>> ? ? ? if (omap_irq_pending() || need_resched())
>> ? ? ? ? ? ? ? goto out;
>>
>> + ? ? trace_power_start(POWER_CSTATE, 1, smp_processor_id());
>> + ? ? trace_cpu_idle(1, smp_processor_id());
>> +
>
> This default idle code won't be used when you enable the
> CONFIG_CPUIDLE. That case the cpuidle34xx.c idle code gets
> registered.
That is correct. OMAP has a default idle handler (omap3_pm_idle) and a
cpuidle handler (omap3_enter_idle in
arch/arm/mach-omap2/cpuidle34xx.c).

> Shouldn't you patch that code instead? This is more or less
> dead code and it is just like default idle code when idle
> drivers isn't registered.
The cpuidle framework already is instrumented in a generic way. This
code adds the instrumentation to the default idle handler so that all
cases are covered. BTW the patch description gives that information.

If there is dead code then it is not only the code from this patch but
all the code for the default idle handler.

Thanks for reviewing.

Regards,
Jean

>
>
>> ? ? ? omap_sram_idle();
>>
>> + ? ? trace_power_end(smp_processor_id());
>> + ? ? trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
>> +
>> ?out:
>> ? ? ? local_fiq_enable();
>> ? ? ? local_irq_enable();
>> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-
>> omap2/powerdomain.c
>> index eaed0df..1495eed 100644
>> --- a/arch/arm/mach-omap2/powerdomain.c
>> +++ b/arch/arm/mach-omap2/powerdomain.c
>> @@ -19,12 +19,15 @@
>> ?#include <linux/list.h>
>> ?#include <linux/errno.h>
>> ?#include <linux/string.h>
>> +#include <trace/events/power.h>
>> +
>> ?#include "cm2xxx_3xxx.h"
>> ?#include "prcm44xx.h"
>> ?#include "cm44xx.h"
>> ?#include "prm2xxx_3xxx.h"
>> ?#include "prm44xx.h"
>>
>> +#include <asm/cpu.h>
>> ?#include <plat/cpu.h>
>> ?#include "powerdomain.h"
>> ?#include "clockdomain.h"
>> @@ -32,6 +35,8 @@
>>
>> ?#include "pm.h"
>>
>> +#define PWRDM_TRACE_STATES_FLAG ? ? ?(1<<31)
>> +
>> ?enum {
>> ? ? ? PWRDM_STATE_NOW = 0,
>> ? ? ? PWRDM_STATE_PREV,
>> @@ -130,8 +135,7 @@ static void
>> _update_logic_membank_counters(struct powerdomain *pwrdm)
>> ?static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
>> ?{
>>
>> - ? ? int prev;
>> - ? ? int state;
>> + ? ? int prev, state, trace_state = 0;
>>
>> ? ? ? if (pwrdm == NULL)
>> ? ? ? ? ? ? ? return -EINVAL;
>> @@ -148,6 +152,17 @@ static int _pwrdm_state_switch(struct
>> powerdomain *pwrdm, int flag)
>> ? ? ? ? ? ? ? ? ? ? ? pwrdm->state_counter[prev]++;
>> ? ? ? ? ? ? ? if (prev == PWRDM_POWER_RET)
>> ? ? ? ? ? ? ? ? ? ? ? _update_logic_membank_counters(pwrdm);
>> + ? ? ? ? ? ? /*
>> + ? ? ? ? ? ? ?* If the power domain did not hit the desired state,
>> + ? ? ? ? ? ? ?* generate a trace event with both the desired and hit
>> states
>> + ? ? ? ? ? ? ?*/
>> + ? ? ? ? ? ? if (state != prev) {
>> + ? ? ? ? ? ? ? ? ? ? trace_state = (PWRDM_TRACE_STATES_FLAG |
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?((state & OMAP_POWERSTATE_MASK) <<
> 8)
>> |
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?((prev & OMAP_POWERSTATE_MASK) <<
>> 0));
>> + ? ? ? ? ? ? ? ? ? ? trace_power_domain_target(pwrdm->name,
>> trace_state,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? smp_processor_id());
>> + ? ? ? ? ? ? }
>> ? ? ? ? ? ? ? break;
>> ? ? ? default:
>> ? ? ? ? ? ? ? return -EINVAL;
>> @@ -406,8 +421,13 @@ int pwrdm_set_next_pwrst(struct powerdomain
>> *pwrdm, u8 pwrst)
>> ? ? ? pr_debug("powerdomain: setting next powerstate for %s to
>> %0x\n",
>> ? ? ? ? ? ? ? ?pwrdm->name, pwrst);
>>
>> - ? ? if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst)
>> + ? ? if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
>> + ? ? ? ? ? ? /* Trace the pwrdm desired target state */
>> + ? ? ? ? ? ? trace_power_domain_target(pwrdm->name, pwrst,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? smp_processor_id());
>> + ? ? ? ? ? ? /* Program the pwrdm desired target state */
>> ? ? ? ? ? ? ? ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
>> + ? ? }
>>
>> ? ? ? return ret;
>> ?}
>> --
>> 1.7.2.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-
>> omap" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH] perf: add OMAP support for the new power events
From: Santosh Shilimkar @ 2011-02-21  8:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTiktdLja39dC38E_LciYZK7+pTp3_Sgm9jf5FA4R@mail.gmail.com>

> -----Original Message-----
> From: Jean Pihet [mailto:jean.pihet at newoldbits.com]
> Sent: Monday, February 21, 2011 2:14 PM
> To: Santosh Shilimkar
> Cc: Kevin Hilman; Thomas Renninger; linux-omap at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; Jean Pihet-XID
> Subject: Re: [PATCH] perf: add OMAP support for the new power events
>
> Hi Santosh,
>

[...]

> >> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-
> >> omap2/pm34xx.c
> >> index 2f864e4..d1cc3f4 100644
> >> --- a/arch/arm/mach-omap2/pm34xx.c
> >> +++ b/arch/arm/mach-omap2/pm34xx.c
> >> @@ -29,6 +29,7 @@
> >> ?#include <linux/delay.h>
> >> ?#include <linux/slab.h>
> >> ?#include <linux/console.h>
> >> +#include <trace/events/power.h>
> >>
> >> ?#include <plat/sram.h>
> >> ?#include "clockdomain.h"
> >> @@ -519,8 +520,14 @@ static void omap3_pm_idle(void)
> >> ? ? ? if (omap_irq_pending() || need_resched())
> >> ? ? ? ? ? ? ? goto out;
> >>
> >> + ? ? trace_power_start(POWER_CSTATE, 1, smp_processor_id());
> >> + ? ? trace_cpu_idle(1, smp_processor_id());
> >> +
> >
> > This default idle code won't be used when you enable the
> > CONFIG_CPUIDLE. That case the cpuidle34xx.c idle code gets
> > registered.
> That is correct. OMAP has a default idle handler (omap3_pm_idle) and
> a
> cpuidle handler (omap3_enter_idle in
> arch/arm/mach-omap2/cpuidle34xx.c).
>
> > Shouldn't you patch that code instead? This is more or less
> > dead code and it is just like default idle code when idle
> > drivers isn't registered.
> The cpuidle framework already is instrumented in a generic way. This
> code adds the instrumentation to the default idle handler so that
> all
> cases are covered. BTW the patch description gives that information.
>
> If there is dead code then it is not only the code from this patch
> but
> all the code for the default idle handler.
>
I read your change log. It says.

>> The trace points are for:
>> - default idle handler. Since the cpuidle framework is
>> ? instrumented in the generic way there is no need to
>> ? add trace points in the OMAP specific cpuidle handler;
Now code in cpuilde34xx.c is also OMAP specific and hence the
confusion at least for me.
Regarding dead code, I meant existing code of default handler.

Thanks for clarification.

Regards,
Santosh

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: David Cohen @ 2011-02-21  8:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110221082240.GL3094@legolas.emea.dhcp.ti.com>

On Mon, Feb 21, 2011 at 10:22 AM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Mon, Feb 21, 2011 at 10:18:56AM +0200, Hiroshi DOYU wrote:
>> From: David Cohen <dacohen@gmail.com>
>> Subject: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
>> Date: Wed, 16 Feb 2011 21:35:51 +0200
>>
>> > Add support to register an isr for IOMMU fault situations and adapt it
>> > to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
>> > module might want to be informed when errors happen in order to debug it
>> > or react.
>> >
>> > Signed-off-by: David Cohen <dacohen@gmail.com>
>> > ---
>> > ?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ?| ? 17 +++++++++-
>> > ?arch/arm/plat-omap/include/plat/iommu.h | ? 14 ++++++++-
>> > ?arch/arm/plat-omap/iommu.c ? ? ? ? ? ? ?| ? 52 ++++++++++++++++++++++---------
>> > ?3 files changed, 65 insertions(+), 18 deletions(-)
>> >
>> > diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
>> > index 49a1e5e..adb083e 100644
>> > --- a/arch/arm/mach-omap2/iommu2.c
>> > +++ b/arch/arm/mach-omap2/iommu2.c
>> > @@ -146,18 +146,31 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
>> > ?static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
>> > ?{
>> > ? ? u32 stat, da;
>> > + ? u32 errs = 0;
>> >
>> > ? ? stat = iommu_read_reg(obj, MMU_IRQSTATUS);
>> > ? ? stat &= MMU_IRQ_MASK;
>> > - ? if (!stat)
>> > + ? if (!stat) {
>> > + ? ? ? ? ? *ra = 0;
>> > ? ? ? ? ? ? return 0;
>> > + ? }
>> >
>> > ? ? da = iommu_read_reg(obj, MMU_FAULT_AD);
>> > ? ? *ra = da;
>> >
>> > + ? if (stat & MMU_IRQ_TLBMISS)
>> > + ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TLB_MISS;
>> > + ? if (stat & MMU_IRQ_TRANSLATIONFAULT)
>> > + ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
>> > + ? if (stat & MMU_IRQ_EMUMISS)
>> > + ? ? ? ? ? errs |= OMAP_IOMMU_ERR_EMU_MISS;
>> > + ? if (stat & MMU_IRQ_TABLEWALKFAULT)
>> > + ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
>> > + ? if (stat & MMU_IRQ_MULTIHITFAULT)
>> > + ? ? ? ? ? errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
>> > ? ? iommu_write_reg(obj, stat, MMU_IRQSTATUS);
>> >
>> > - ? return stat;
>> > + ? return errs;
>> > ?}
>> >
>> > ?static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
>> > diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
>> > index 19cbb5e..174f1b9 100644
>> > --- a/arch/arm/plat-omap/include/plat/iommu.h
>> > +++ b/arch/arm/plat-omap/include/plat/iommu.h
>> > @@ -31,6 +31,7 @@ struct iommu {
>> > ? ? struct clk ? ? ?*clk;
>> > ? ? void __iomem ? ?*regbase;
>> > ? ? struct device ? *dev;
>> > + ? void ? ? ? ? ? ?*isr_priv;
>>
>> Ideally I'd like to avoid having "isr_priv" in iommu since it's not
>> used for iommu but client needs the place to pass its info to its
>> custom handler. Any better idea?
>
> I'm not sure if it makes sense as I don't know the mailbox block, but
> maybe moving to GENIRQ ? Then IRQ subsystem would take care of the
> "dev_id"

Not sure if it fits in this case. It's a different module (IOMMU user)
which needs to get a callback from IOMMU when a fault happens.
Is there any GENIRQ usage currently in this scenario?

Br,

David

>
> --
> balbi
>

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: David Cohen @ 2011-02-21  9:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110221.101856.76372714451194378.Hiroshi.DOYU@nokia.com>

On Mon, Feb 21, 2011 at 10:18 AM, Hiroshi DOYU <Hiroshi.DOYU@nokia.com> wrote:
> From: David Cohen <dacohen@gmail.com>
> Subject: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
> Date: Wed, 16 Feb 2011 21:35:51 +0200
>
>> Add support to register an isr for IOMMU fault situations and adapt it
>> to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
>> module might want to be informed when errors happen in order to debug it
>> or react.
>>
>> Signed-off-by: David Cohen <dacohen@gmail.com>
>> ---
>> ?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ?| ? 17 +++++++++-
>> ?arch/arm/plat-omap/include/plat/iommu.h | ? 14 ++++++++-
>> ?arch/arm/plat-omap/iommu.c ? ? ? ? ? ? ?| ? 52 ++++++++++++++++++++++---------
>> ?3 files changed, 65 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
>> index 49a1e5e..adb083e 100644
>> --- a/arch/arm/mach-omap2/iommu2.c
>> +++ b/arch/arm/mach-omap2/iommu2.c
>> @@ -146,18 +146,31 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
>> ?static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
>> ?{
>> ? ? ? u32 stat, da;
>> + ? ? u32 errs = 0;
>>
>> ? ? ? stat = iommu_read_reg(obj, MMU_IRQSTATUS);
>> ? ? ? stat &= MMU_IRQ_MASK;
>> - ? ? if (!stat)
>> + ? ? if (!stat) {
>> + ? ? ? ? ? ? *ra = 0;
>> ? ? ? ? ? ? ? return 0;
>> + ? ? }
>>
>> ? ? ? da = iommu_read_reg(obj, MMU_FAULT_AD);
>> ? ? ? *ra = da;
>>
>> + ? ? if (stat & MMU_IRQ_TLBMISS)
>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TLB_MISS;
>> + ? ? if (stat & MMU_IRQ_TRANSLATIONFAULT)
>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
>> + ? ? if (stat & MMU_IRQ_EMUMISS)
>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_EMU_MISS;
>> + ? ? if (stat & MMU_IRQ_TABLEWALKFAULT)
>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
>> + ? ? if (stat & MMU_IRQ_MULTIHITFAULT)
>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
>> ? ? ? iommu_write_reg(obj, stat, MMU_IRQSTATUS);
>>
>> - ? ? return stat;
>> + ? ? return errs;
>> ?}
>>
>> ?static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
>> diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
>> index 19cbb5e..174f1b9 100644
>> --- a/arch/arm/plat-omap/include/plat/iommu.h
>> +++ b/arch/arm/plat-omap/include/plat/iommu.h
>> @@ -31,6 +31,7 @@ struct iommu {
>> ? ? ? struct clk ? ? ?*clk;
>> ? ? ? void __iomem ? ?*regbase;
>> ? ? ? struct device ? *dev;
>> + ? ? void ? ? ? ? ? ?*isr_priv;
>
> Ideally I'd like to avoid having "isr_priv" in iommu since it's not
> used for iommu but client needs the place to pass its info to its
> custom handler. Any better idea?

(*isr)() relies in the same situation, as it belongs to the client.
Without this priv_data, it's necessary to create a global variable to
store client's private data on client side. IMO, it is worse.

Br,

David

>
>
>> ? ? ? unsigned int ? ?refcount;
>> ? ? ? struct mutex ? ?iommu_lock; ? ? /* global for this whole object */
>> @@ -47,7 +48,7 @@ struct iommu {
>> ? ? ? struct list_head ? ? ? ?mmap;
>> ? ? ? struct mutex ? ? ? ? ? ?mmap_lock; /* protect mmap */
>>
>> - ? ? int (*isr)(struct iommu *obj);
>> + ? ? int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv);
>>
>> ? ? ? void *ctx; /* iommu context: registres saved area */
>> ? ? ? u32 da_start;
>> @@ -109,6 +110,13 @@ struct iommu_platform_data {
>> ? ? ? u32 da_end;
>> ?};
>>
>> +/* IOMMU errors */
>> +#define OMAP_IOMMU_ERR_TLB_MISS ? ? ? ? ? ? ?(1 << 0)
>> +#define OMAP_IOMMU_ERR_TRANS_FAULT ? (1 << 1)
>> +#define OMAP_IOMMU_ERR_EMU_MISS ? ? ? ? ? ? ?(1 << 2)
>> +#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3)
>> +#define OMAP_IOMMU_ERR_MULTIHIT_FAULT ? ? ? ?(1 << 4)
>> +
>> ?#if defined(CONFIG_ARCH_OMAP1)
>> ?#error "iommu for this processor not implemented yet"
>> ?#else
>> @@ -161,6 +169,10 @@ extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
>> ?extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
>> ?extern struct iommu *iommu_get(const char *name);
>> ?extern void iommu_put(struct iommu *obj);
>> +extern int iommu_set_isr(const char *name,
>> + ? ? ? ? ? ? ? ? ? ? ?int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *priv),
>> + ? ? ? ? ? ? ? ? ? ? ?void *isr_priv);
>>
>> ?extern void iommu_save_ctx(struct iommu *obj);
>> ?extern void iommu_restore_ctx(struct iommu *obj);
>> diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
>> index f55f458..b0e0efc 100644
>> --- a/arch/arm/plat-omap/iommu.c
>> +++ b/arch/arm/plat-omap/iommu.c
>> @@ -780,25 +780,19 @@ static void iopgtable_clear_entry_all(struct iommu *obj)
>> ? */
>> ?static irqreturn_t iommu_fault_handler(int irq, void *data)
>> ?{
>> - ? ? u32 stat, da;
>> + ? ? u32 da, errs;
>> ? ? ? u32 *iopgd, *iopte;
>> - ? ? int err = -EIO;
>> ? ? ? struct iommu *obj = data;
>>
>> ? ? ? if (!obj->refcount)
>> ? ? ? ? ? ? ? return IRQ_NONE;
>>
>> - ? ? /* Dynamic loading TLB or PTE */
>> - ? ? if (obj->isr)
>> - ? ? ? ? ? ? err = obj->isr(obj);
>> -
>> - ? ? if (!err)
>> - ? ? ? ? ? ? return IRQ_HANDLED;
>> -
>> ? ? ? clk_enable(obj->clk);
>> - ? ? stat = iommu_report_fault(obj, &da);
>> + ? ? errs = iommu_report_fault(obj, &da);
>> ? ? ? clk_disable(obj->clk);
>> - ? ? if (!stat)
>> +
>> + ? ? /* Fault callback or TLB/PTE Dynamic loading */
>> + ? ? if (obj->isr && !obj->isr(obj, da, errs, obj->isr_priv))
>> ? ? ? ? ? ? ? return IRQ_HANDLED;
>>
>> ? ? ? iommu_disable(obj);
>> @@ -806,15 +800,16 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
>> ? ? ? iopgd = iopgd_offset(obj, da);
>>
>> ? ? ? if (!iopgd_is_table(*iopgd)) {
>> - ? ? ? ? ? ? dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", obj->name,
>> - ? ? ? ? ? ? ? ? ? ? da, iopgd, *iopgd);
>> + ? ? ? ? ? ? dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p "
>> + ? ? ? ? ? ? ? ? ? ? "*pgd:px%08x\n", obj->name, errs, da, iopgd, *iopgd);
>> ? ? ? ? ? ? ? return IRQ_NONE;
>> ? ? ? }
>>
>> ? ? ? iopte = iopte_offset(iopgd, da);
>>
>> - ? ? dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
>> - ? ? ? ? ? ? obj->name, da, iopgd, *iopgd, iopte, *iopte);
>> + ? ? dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x "
>> + ? ? ? ? ? ? "pte:0x%p *pte:0x%08x\n", obj->name, errs, da, iopgd, *iopgd,
>> + ? ? ? ? ? ? iopte, *iopte);
>>
>> ? ? ? return IRQ_NONE;
>> ?}
>> @@ -917,6 +912,33 @@ void iommu_put(struct iommu *obj)
>> ?}
>> ?EXPORT_SYMBOL_GPL(iommu_put);
>>
>> +int iommu_set_isr(const char *name,
>> + ? ? ? ? ? ? ? int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ?void *priv),
>> + ? ? ? ? ? ? ? void *isr_priv)
>> +{
>> + ? ? struct device *dev;
>> + ? ? struct iommu *obj;
>> +
>> + ? ? dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?device_match_by_alias);
>> + ? ? if (!dev)
>> + ? ? ? ? ? ? return -ENODEV;
>> +
>> + ? ? obj = to_iommu(dev);
>> + ? ? mutex_lock(&obj->iommu_lock);
>> + ? ? if (obj->refcount != 0) {
>> + ? ? ? ? ? ? mutex_unlock(&obj->iommu_lock);
>> + ? ? ? ? ? ? return -EBUSY;
>> + ? ? }
>> + ? ? obj->isr = isr;
>> + ? ? obj->isr_priv = isr_priv;
>> + ? ? mutex_unlock(&obj->iommu_lock);
>> +
>> + ? ? return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(iommu_set_isr);
>> +
>> ?/*
>> ? * ? OMAP Device MMU(IOMMU) detection
>> ? */
>> --
>> 1.7.2.3
>>
>

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Felipe Balbi @ 2011-02-21  9:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTinTCGhH9HgGEr1ciHL5Vf+gQxecr17O6Z9OTOWv@mail.gmail.com>

Hi,

On Mon, Feb 21, 2011 at 10:57:45AM +0200, David Cohen wrote:
> >> Ideally I'd like to avoid having "isr_priv" in iommu since it's not
> >> used for iommu but client needs the place to pass its info to its
> >> custom handler. Any better idea?
> >
> > I'm not sure if it makes sense as I don't know the mailbox block, but
> > maybe moving to GENIRQ ? Then IRQ subsystem would take care of the
> > "dev_id"
> 
> Not sure if it fits in this case. It's a different module (IOMMU user)
> which needs to get a callback from IOMMU when a fault happens.
> Is there any GENIRQ usage currently in this scenario?

No, that's not how GENIRQ is supposed to be used. You will need a
function pointer, like you added.

-- 
balbi

^ permalink raw reply

* [RFC PATCH 2/2] ARMv7: Invalidate the TLB before freeing page tables
From: Catalin Marinas @ 2011-02-21  9:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110220121227.GB14495@n2100.arm.linux.org.uk>

On 20 February 2011 12:12, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 15, 2011 at 02:42:06PM +0000, Catalin Marinas wrote:
>> On Tue, 2011-02-15 at 12:14 +0000, Russell King - ARM Linux wrote:
>> > On Tue, Feb 15, 2011 at 11:32:42AM +0000, Russell King - ARM Linux wrote:
>> > > The point of TLB shootdown is that we unmap the entries from the page
>> > > tables, then issue the TLB flushes, and then free the pages and page
>> > > tables after that. ?All that Peter's patch tries to do is to get ARM to
>> > > use the generic stuff.
>> >
>> > As Peter's patch preserves the current behaviour, that's not sufficient.
>> > So, let's do this our own way and delay pages and page table frees on
>> > ARMv6 and v7. ?Untested.
>>
>> ARMv7 should be enough, I'm not aware of any pre-v7 with this behaviour.
>
> ARM11MPCore. ?Any SMP system can access a page which was free'd by the
> tlb code but hasn't been flushed from the hardware TLBs. ?So maybe we
> want it to be "defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)" ?

In practice, since the hardware TLB does not store higher level
entries on existing v6 cores, there is no cached value pointing to the
freed pte page. In theory, we first clear the pmd entry but another
CPU could be doing a PTW at the same time and had already read the pmd
before being cleared. But the timing constraints are difficult to
reproduce in practice.

Anyway, I'm ok with your original patch or the CONFIG_SMP case you
mentioned above. Whichever you prefer.

-- 
Catalin

^ permalink raw reply

* [PATCH 1/2] ARM: l2x0: Errata fix for flush by Way operation can cause data corruption
From: Catalin Marinas @ 2011-02-21  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298032525-21115-2-git-send-email-santosh.shilimkar@ti.com>

On 18 February 2011 12:35, Santosh Shilimkar <santosh.shilimkar@ti.com> wrote:
> PL310 implements the Clean & Invalidate by Way L2 cache maintenance
> operation (offset 0x7FC). This operation runs in background so that
> PL310 can handle normal accesses while it is in progress. Under very
> rare circumstances, due to this erratum, write data can be lost when
> PL310 treats a cacheable write transaction during a Clean & Invalidate
> by Way operation.
>
> Workaround:
> Disable Write-Back and Cache Linefill (Debug Control Register)
> Clean & Invalidate by Way (0x7FC)
> Re-enable Write-Back and Cache Linefill (Debug Control Register)
>
> This patch also removes any OMAP dependency on PL310 Errata's
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Hiroshi DOYU @ 2011-02-21  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTimdWknRuk+QSV3bFU=qQGMsmmH-dj6a_QaTp49r@mail.gmail.com>

From: ext David Cohen <dacohen@gmail.com>
Subject: Re: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
Date: Mon, 21 Feb 2011 11:07:01 +0200

> On Mon, Feb 21, 2011 at 10:18 AM, Hiroshi DOYU <Hiroshi.DOYU@nokia.com> wrote:
>> From: David Cohen <dacohen@gmail.com>
>> Subject: [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
>> Date: Wed, 16 Feb 2011 21:35:51 +0200
>>
>>> Add support to register an isr for IOMMU fault situations and adapt it
>>> to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
>>> module might want to be informed when errors happen in order to debug it
>>> or react.
>>>
>>> Signed-off-by: David Cohen <dacohen@gmail.com>
>>> ---
>>> ?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ?| ? 17 +++++++++-
>>> ?arch/arm/plat-omap/include/plat/iommu.h | ? 14 ++++++++-
>>> ?arch/arm/plat-omap/iommu.c ? ? ? ? ? ? ?| ? 52 ++++++++++++++++++++++---------
>>> ?3 files changed, 65 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
>>> index 49a1e5e..adb083e 100644
>>> --- a/arch/arm/mach-omap2/iommu2.c
>>> +++ b/arch/arm/mach-omap2/iommu2.c
>>> @@ -146,18 +146,31 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
>>> ?static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
>>> ?{
>>> ? ? ? u32 stat, da;
>>> + ? ? u32 errs = 0;
>>>
>>> ? ? ? stat = iommu_read_reg(obj, MMU_IRQSTATUS);
>>> ? ? ? stat &= MMU_IRQ_MASK;
>>> - ? ? if (!stat)
>>> + ? ? if (!stat) {
>>> + ? ? ? ? ? ? *ra = 0;
>>> ? ? ? ? ? ? ? return 0;
>>> + ? ? }
>>>
>>> ? ? ? da = iommu_read_reg(obj, MMU_FAULT_AD);
>>> ? ? ? *ra = da;
>>>
>>> + ? ? if (stat & MMU_IRQ_TLBMISS)
>>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TLB_MISS;
>>> + ? ? if (stat & MMU_IRQ_TRANSLATIONFAULT)
>>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
>>> + ? ? if (stat & MMU_IRQ_EMUMISS)
>>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_EMU_MISS;
>>> + ? ? if (stat & MMU_IRQ_TABLEWALKFAULT)
>>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
>>> + ? ? if (stat & MMU_IRQ_MULTIHITFAULT)
>>> + ? ? ? ? ? ? errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
>>> ? ? ? iommu_write_reg(obj, stat, MMU_IRQSTATUS);
>>>
>>> - ? ? return stat;
>>> + ? ? return errs;
>>> ?}
>>>
>>> ?static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
>>> diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
>>> index 19cbb5e..174f1b9 100644
>>> --- a/arch/arm/plat-omap/include/plat/iommu.h
>>> +++ b/arch/arm/plat-omap/include/plat/iommu.h
>>> @@ -31,6 +31,7 @@ struct iommu {
>>> ? ? ? struct clk ? ? ?*clk;
>>> ? ? ? void __iomem ? ?*regbase;
>>> ? ? ? struct device ? *dev;
>>> + ? ? void ? ? ? ? ? ?*isr_priv;
>>
>> Ideally I'd like to avoid having "isr_priv" in iommu since it's not
>> used for iommu but client needs the place to pass its info to its
>> custom handler. Any better idea?
> 
> (*isr)() relies in the same situation, as it belongs to the client.
> Without this priv_data, it's necessary to create a global variable to
> store client's private data on client side. IMO, it is worse.

Ok, I see. Let's go with this. Thanks.

^ permalink raw reply

* [PATCH v3 0/2] OMAP: IOMMU fault callback support
From: Hiroshi DOYU @ 2011-02-21  9:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297884951-3019-1-git-send-email-dacohen@gmail.com>

From: David Cohen <dacohen@gmail.com>
Subject: [PATCH v3 0/2] OMAP: IOMMU fault callback support
Date: Wed, 16 Feb 2011 21:35:49 +0200

> Hi,
> 
> This patch set adapts current (*isr)() to be used as fault callback.
> IOMMU faults might be very difficult to reproduce and then to figure out
> the source of the problem. Currently IOMMU driver prints not so useful
> debug message and does not notice user about such issue.
> With a fault callback, IOMMU user may debug much more useful information
> and/or react to go back to a valid state.

Tony, please put them in your queue too. Thanks.

> Br,
> 
> David
> ---
> 
> David Cohen (2):
>   OMAP2+: IOMMU: don't print fault warning on specific layer
>   OMAP: IOMMU: add support to callback during fault handling

Acked-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>

> 
>  arch/arm/mach-omap2/iommu2.c            |   33 +++++++++-----------
>  arch/arm/plat-omap/include/plat/iommu.h |   14 ++++++++-
>  arch/arm/plat-omap/iommu.c              |   52 ++++++++++++++++++++++---------
>  3 files changed, 65 insertions(+), 34 deletions(-)
> 
> -- 
> 1.7.2.3
> 

^ permalink raw reply

* [PATCH 1/5] ARM: imx53: add sdhc pad settings
From: Richard Zhao @ 2011-02-21  9:54 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Richard Zhao <richard.zhao@freescale.com>

diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
index bae7fd0..e95d9cb 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx53.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
@@ -27,6 +27,9 @@
 
 #define MX53_UART_PAD_CTRL		(PAD_CTL_PKE | PAD_CTL_PUE |	\
 		PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+#define MX53_SDHC_PAD_CTRL 	(PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+				PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH | \
+				PAD_CTL_SRE_FAST)
 
 #define _MX53_PAD_GPIO_19__KPP_COL_5		IOMUX_PAD(0x348, 0x20, 0, 0x840, 0, 0)
 #define _MX53_PAD_GPIO_19__GPIO4_5		IOMUX_PAD(0x348, 0x20, 1, 0x0, 0, 0)
@@ -2057,13 +2060,13 @@
 #define MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7		(_MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B		(_MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_RESET_B__GPIO7_4		(_MX53_PAD_PATA_RESET_B__GPIO7_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_RESET_B__ESDHC3_CMD		(_MX53_PAD_PATA_RESET_B__ESDHC3_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__ESDHC3_CMD		(_MX53_PAD_PATA_RESET_B__ESDHC3_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_RESET_B__UART1_CTS		(_MX53_PAD_PATA_RESET_B__UART1_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_RESET_B__CAN2_TXCAN		(_MX53_PAD_PATA_RESET_B__CAN2_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0		(_MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_IORDY__PATA_IORDY		(_MX53_PAD_PATA_IORDY__PATA_IORDY | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_IORDY__GPIO7_5		(_MX53_PAD_PATA_IORDY__GPIO7_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_IORDY__ESDHC3_CLK		(_MX53_PAD_PATA_IORDY__ESDHC3_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__ESDHC3_CLK		(_MX53_PAD_PATA_IORDY__ESDHC3_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_IORDY__UART1_RTS		(_MX53_PAD_PATA_IORDY__UART1_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_IORDY__CAN2_RXCAN		(_MX53_PAD_PATA_IORDY__CAN2_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1		(_MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
@@ -2074,12 +2077,12 @@
 #define MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2		(_MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DA_1__PATA_DA_1		(_MX53_PAD_PATA_DA_1__PATA_DA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DA_1__GPIO7_7		(_MX53_PAD_PATA_DA_1__GPIO7_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DA_1__ESDHC4_CMD		(_MX53_PAD_PATA_DA_1__ESDHC4_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__ESDHC4_CMD		(_MX53_PAD_PATA_DA_1__ESDHC4_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DA_1__UART3_CTS		(_MX53_PAD_PATA_DA_1__UART3_CTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
 #define MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3		(_MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DA_2__PATA_DA_2		(_MX53_PAD_PATA_DA_2__PATA_DA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DA_2__GPIO7_8		(_MX53_PAD_PATA_DA_2__GPIO7_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DA_2__ESDHC4_CLK		(_MX53_PAD_PATA_DA_2__ESDHC4_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__ESDHC4_CLK		(_MX53_PAD_PATA_DA_2__ESDHC4_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DA_2__UART3_RTS		(_MX53_PAD_PATA_DA_2__UART3_RTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
 #define MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4		(_MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_CS_0__PATA_CS_0		(_MX53_PAD_PATA_CS_0__PATA_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
@@ -2093,124 +2096,124 @@
 #define MX53_PAD_PATA_DATA0__PATA_DATA_0		(_MX53_PAD_PATA_DATA0__PATA_DATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA0__GPIO2_0		(_MX53_PAD_PATA_DATA0__GPIO2_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA0__EMI_NANDF_D_0		(_MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA0__ESDHC3_DAT4		(_MX53_PAD_PATA_DATA0__ESDHC3_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__ESDHC3_DAT4		(_MX53_PAD_PATA_DATA0__ESDHC3_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0		(_MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0		(_MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7		(_MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA1__PATA_DATA_1		(_MX53_PAD_PATA_DATA1__PATA_DATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA1__GPIO2_1		(_MX53_PAD_PATA_DATA1__GPIO2_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA1__EMI_NANDF_D_1		(_MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA1__ESDHC3_DAT5		(_MX53_PAD_PATA_DATA1__ESDHC3_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__ESDHC3_DAT5		(_MX53_PAD_PATA_DATA1__ESDHC3_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1		(_MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1		(_MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA2__PATA_DATA_2		(_MX53_PAD_PATA_DATA2__PATA_DATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA2__GPIO2_2		(_MX53_PAD_PATA_DATA2__GPIO2_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA2__EMI_NANDF_D_2		(_MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA2__ESDHC3_DAT6		(_MX53_PAD_PATA_DATA2__ESDHC3_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__ESDHC3_DAT6		(_MX53_PAD_PATA_DATA2__ESDHC3_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2		(_MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2		(_MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA3__PATA_DATA_3		(_MX53_PAD_PATA_DATA3__PATA_DATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA3__GPIO2_3		(_MX53_PAD_PATA_DATA3__GPIO2_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA3__EMI_NANDF_D_3		(_MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA3__ESDHC3_DAT7		(_MX53_PAD_PATA_DATA3__ESDHC3_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__ESDHC3_DAT7		(_MX53_PAD_PATA_DATA3__ESDHC3_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3		(_MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3		(_MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA4__PATA_DATA_4		(_MX53_PAD_PATA_DATA4__PATA_DATA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA4__GPIO2_4		(_MX53_PAD_PATA_DATA4__GPIO2_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA4__EMI_NANDF_D_4		(_MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA4__ESDHC4_DAT4		(_MX53_PAD_PATA_DATA4__ESDHC4_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__ESDHC4_DAT4		(_MX53_PAD_PATA_DATA4__ESDHC4_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4		(_MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4		(_MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA5__PATA_DATA_5		(_MX53_PAD_PATA_DATA5__PATA_DATA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA5__GPIO2_5		(_MX53_PAD_PATA_DATA5__GPIO2_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA5__EMI_NANDF_D_5		(_MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA5__ESDHC4_DAT5		(_MX53_PAD_PATA_DATA5__ESDHC4_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__ESDHC4_DAT5		(_MX53_PAD_PATA_DATA5__ESDHC4_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5		(_MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5		(_MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA6__PATA_DATA_6		(_MX53_PAD_PATA_DATA6__PATA_DATA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA6__GPIO2_6		(_MX53_PAD_PATA_DATA6__GPIO2_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA6__EMI_NANDF_D_6		(_MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA6__ESDHC4_DAT6		(_MX53_PAD_PATA_DATA6__ESDHC4_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__ESDHC4_DAT6		(_MX53_PAD_PATA_DATA6__ESDHC4_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6		(_MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6		(_MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA7__PATA_DATA_7		(_MX53_PAD_PATA_DATA7__PATA_DATA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA7__GPIO2_7		(_MX53_PAD_PATA_DATA7__GPIO2_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA7__EMI_NANDF_D_7		(_MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA7__ESDHC4_DAT7		(_MX53_PAD_PATA_DATA7__ESDHC4_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__ESDHC4_DAT7		(_MX53_PAD_PATA_DATA7__ESDHC4_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7		(_MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7		(_MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA8__PATA_DATA_8		(_MX53_PAD_PATA_DATA8__PATA_DATA_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA8__GPIO2_8		(_MX53_PAD_PATA_DATA8__GPIO2_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA8__ESDHC1_DAT4		(_MX53_PAD_PATA_DATA8__ESDHC1_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__ESDHC1_DAT4		(_MX53_PAD_PATA_DATA8__ESDHC1_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA8__EMI_NANDF_D_8		(_MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA8__ESDHC3_DAT0		(_MX53_PAD_PATA_DATA8__ESDHC3_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__ESDHC3_DAT0		(_MX53_PAD_PATA_DATA8__ESDHC3_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8		(_MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8		(_MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA9__PATA_DATA_9		(_MX53_PAD_PATA_DATA9__PATA_DATA_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA9__GPIO2_9		(_MX53_PAD_PATA_DATA9__GPIO2_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA9__ESDHC1_DAT5		(_MX53_PAD_PATA_DATA9__ESDHC1_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__ESDHC1_DAT5		(_MX53_PAD_PATA_DATA9__ESDHC1_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA9__EMI_NANDF_D_9		(_MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA9__ESDHC3_DAT1		(_MX53_PAD_PATA_DATA9__ESDHC3_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__ESDHC3_DAT1		(_MX53_PAD_PATA_DATA9__ESDHC3_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9		(_MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9		(_MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA10__PATA_DATA_10		(_MX53_PAD_PATA_DATA10__PATA_DATA_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA10__GPIO2_10		(_MX53_PAD_PATA_DATA10__GPIO2_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA10__ESDHC1_DAT6		(_MX53_PAD_PATA_DATA10__ESDHC1_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__ESDHC1_DAT6		(_MX53_PAD_PATA_DATA10__ESDHC1_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA10__EMI_NANDF_D_10		(_MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA10__ESDHC3_DAT2		(_MX53_PAD_PATA_DATA10__ESDHC3_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__ESDHC3_DAT2		(_MX53_PAD_PATA_DATA10__ESDHC3_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10		(_MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10		(_MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA11__PATA_DATA_11		(_MX53_PAD_PATA_DATA11__PATA_DATA_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA11__GPIO2_11		(_MX53_PAD_PATA_DATA11__GPIO2_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA11__ESDHC1_DAT7		(_MX53_PAD_PATA_DATA11__ESDHC1_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__ESDHC1_DAT7		(_MX53_PAD_PATA_DATA11__ESDHC1_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA11__EMI_NANDF_D_11		(_MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA11__ESDHC3_DAT3		(_MX53_PAD_PATA_DATA11__ESDHC3_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__ESDHC3_DAT3		(_MX53_PAD_PATA_DATA11__ESDHC3_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11		(_MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11		(_MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA12__PATA_DATA_12		(_MX53_PAD_PATA_DATA12__PATA_DATA_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA12__GPIO2_12		(_MX53_PAD_PATA_DATA12__GPIO2_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA12__ESDHC2_DAT4		(_MX53_PAD_PATA_DATA12__ESDHC2_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__ESDHC2_DAT4		(_MX53_PAD_PATA_DATA12__ESDHC2_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA12__EMI_NANDF_D_12		(_MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA12__ESDHC4_DAT0		(_MX53_PAD_PATA_DATA12__ESDHC4_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__ESDHC4_DAT0		(_MX53_PAD_PATA_DATA12__ESDHC4_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12		(_MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12		(_MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA13__PATA_DATA_13		(_MX53_PAD_PATA_DATA13__PATA_DATA_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA13__GPIO2_13		(_MX53_PAD_PATA_DATA13__GPIO2_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA13__ESDHC2_DAT5		(_MX53_PAD_PATA_DATA13__ESDHC2_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__ESDHC2_DAT5		(_MX53_PAD_PATA_DATA13__ESDHC2_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA13__EMI_NANDF_D_13		(_MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA13__ESDHC4_DAT1		(_MX53_PAD_PATA_DATA13__ESDHC4_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__ESDHC4_DAT1		(_MX53_PAD_PATA_DATA13__ESDHC4_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13		(_MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13		(_MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA14__PATA_DATA_14		(_MX53_PAD_PATA_DATA14__PATA_DATA_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA14__GPIO2_14		(_MX53_PAD_PATA_DATA14__GPIO2_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA14__ESDHC2_DAT6		(_MX53_PAD_PATA_DATA14__ESDHC2_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__ESDHC2_DAT6		(_MX53_PAD_PATA_DATA14__ESDHC2_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA14__EMI_NANDF_D_14		(_MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA14__ESDHC4_DAT2		(_MX53_PAD_PATA_DATA14__ESDHC4_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__ESDHC4_DAT2		(_MX53_PAD_PATA_DATA14__ESDHC4_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14		(_MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14		(_MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA15__PATA_DATA_15		(_MX53_PAD_PATA_DATA15__PATA_DATA_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA15__GPIO2_15		(_MX53_PAD_PATA_DATA15__GPIO2_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA15__ESDHC2_DAT7		(_MX53_PAD_PATA_DATA15__ESDHC2_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__ESDHC2_DAT7		(_MX53_PAD_PATA_DATA15__ESDHC2_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA15__EMI_NANDF_D_15		(_MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_PATA_DATA15__ESDHC4_DAT3		(_MX53_PAD_PATA_DATA15__ESDHC4_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__ESDHC4_DAT3		(_MX53_PAD_PATA_DATA15__ESDHC4_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15		(_MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15		(_MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_DATA0__ESDHC1_DAT0		(_MX53_PAD_SD1_DATA0__ESDHC1_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__ESDHC1_DAT0		(_MX53_PAD_SD1_DATA0__ESDHC1_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_DATA0__GPIO1_16		(_MX53_PAD_SD1_DATA0__GPIO1_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA0__GPT_CAPIN1		(_MX53_PAD_SD1_DATA0__GPT_CAPIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA0__CSPI_MISO		(_MX53_PAD_SD1_DATA0__CSPI_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA0__CCM_PLL3_BYP		(_MX53_PAD_SD1_DATA0__CCM_PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_DATA1__ESDHC1_DAT1		(_MX53_PAD_SD1_DATA1__ESDHC1_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__ESDHC1_DAT1		(_MX53_PAD_SD1_DATA1__ESDHC1_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_DATA1__GPIO1_17		(_MX53_PAD_SD1_DATA1__GPIO1_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA1__GPT_CAPIN2		(_MX53_PAD_SD1_DATA1__GPT_CAPIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA1__CSPI_SS0		(_MX53_PAD_SD1_DATA1__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA1__CCM_PLL4_BYP		(_MX53_PAD_SD1_DATA1__CCM_PLL4_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_CMD__ESDHC1_CMD		(_MX53_PAD_SD1_CMD__ESDHC1_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__ESDHC1_CMD		(_MX53_PAD_SD1_CMD__ESDHC1_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_CMD__GPIO1_18		(_MX53_PAD_SD1_CMD__GPIO1_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CMD__GPT_CMPOUT1		(_MX53_PAD_SD1_CMD__GPT_CMPOUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CMD__CSPI_MOSI		(_MX53_PAD_SD1_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CMD__CCM_PLL1_BYP		(_MX53_PAD_SD1_CMD__CCM_PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_DATA2__ESDHC1_DAT2		(_MX53_PAD_SD1_DATA2__ESDHC1_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__ESDHC1_DAT2		(_MX53_PAD_SD1_DATA2__ESDHC1_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_DATA2__GPIO1_19		(_MX53_PAD_SD1_DATA2__GPIO1_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA2__GPT_CMPOUT2		(_MX53_PAD_SD1_DATA2__GPT_CMPOUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA2__PWM2_PWMO		(_MX53_PAD_SD1_DATA2__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
@@ -2218,13 +2221,13 @@
 #define MX53_PAD_SD1_DATA2__CSPI_SS1		(_MX53_PAD_SD1_DATA2__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB		(_MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA2__CCM_PLL2_BYP		(_MX53_PAD_SD1_DATA2__CCM_PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_CLK__ESDHC1_CLK		(_MX53_PAD_SD1_CLK__ESDHC1_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__ESDHC1_CLK		(_MX53_PAD_SD1_CLK__ESDHC1_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_CLK__GPIO1_20		(_MX53_PAD_SD1_CLK__GPIO1_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CLK__OSC32k_32K_OUT		(_MX53_PAD_SD1_CLK__OSC32k_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CLK__GPT_CLKIN		(_MX53_PAD_SD1_CLK__GPT_CLKIN | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CLK__CSPI_SCLK		(_MX53_PAD_SD1_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_CLK__SATA_PHY_DTB_0		(_MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD1_DATA3__ESDHC1_DAT3		(_MX53_PAD_SD1_DATA3__ESDHC1_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__ESDHC1_DAT3		(_MX53_PAD_SD1_DATA3__ESDHC1_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD1_DATA3__GPIO1_21		(_MX53_PAD_SD1_DATA3__GPIO1_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA3__GPT_CMPOUT3		(_MX53_PAD_SD1_DATA3__GPT_CMPOUT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA3__PWM1_PWMO		(_MX53_PAD_SD1_DATA3__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
@@ -2232,37 +2235,37 @@
 #define MX53_PAD_SD1_DATA3__CSPI_SS2		(_MX53_PAD_SD1_DATA3__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB		(_MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1		(_MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_CLK__ESDHC2_CLK		(_MX53_PAD_SD2_CLK__ESDHC2_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__ESDHC2_CLK		(_MX53_PAD_SD2_CLK__ESDHC2_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_CLK__GPIO1_10		(_MX53_PAD_SD2_CLK__GPIO1_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CLK__KPP_COL_5		(_MX53_PAD_SD2_CLK__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS		(_MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CLK__CSPI_SCLK		(_MX53_PAD_SD2_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CLK__SCC_RANDOM_V		(_MX53_PAD_SD2_CLK__SCC_RANDOM_V | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_CMD__ESDHC2_CMD		(_MX53_PAD_SD2_CMD__ESDHC2_CMD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__ESDHC2_CMD		(_MX53_PAD_SD2_CMD__ESDHC2_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_CMD__GPIO1_11		(_MX53_PAD_SD2_CMD__GPIO1_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CMD__KPP_ROW_5		(_MX53_PAD_SD2_CMD__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC		(_MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CMD__CSPI_MOSI		(_MX53_PAD_SD2_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_CMD__SCC_RANDOM		(_MX53_PAD_SD2_CMD__SCC_RANDOM | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_DATA3__ESDHC2_DAT3		(_MX53_PAD_SD2_DATA3__ESDHC2_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__ESDHC2_DAT3		(_MX53_PAD_SD2_DATA3__ESDHC2_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_DATA3__GPIO1_12		(_MX53_PAD_SD2_DATA3__GPIO1_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA3__KPP_COL_6		(_MX53_PAD_SD2_DATA3__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC		(_MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA3__CSPI_SS2		(_MX53_PAD_SD2_DATA3__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA3__SJC_DONE		(_MX53_PAD_SD2_DATA3__SJC_DONE | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_DATA2__ESDHC2_DAT2		(_MX53_PAD_SD2_DATA2__ESDHC2_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__ESDHC2_DAT2		(_MX53_PAD_SD2_DATA2__ESDHC2_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_DATA2__GPIO1_13		(_MX53_PAD_SD2_DATA2__GPIO1_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA2__KPP_ROW_6		(_MX53_PAD_SD2_DATA2__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD		(_MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA2__CSPI_SS1		(_MX53_PAD_SD2_DATA2__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA2__SJC_FAIL		(_MX53_PAD_SD2_DATA2__SJC_FAIL | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_DATA1__ESDHC2_DAT1		(_MX53_PAD_SD2_DATA1__ESDHC2_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__ESDHC2_DAT1		(_MX53_PAD_SD2_DATA1__ESDHC2_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_DATA1__GPIO1_14		(_MX53_PAD_SD2_DATA1__GPIO1_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA1__KPP_COL_7		(_MX53_PAD_SD2_DATA1__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS		(_MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA1__CSPI_SS0		(_MX53_PAD_SD2_DATA1__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA1__RTIC_SEC_VIO		(_MX53_PAD_SD2_DATA1__RTIC_SEC_VIO | MUX_PAD_CTRL(NO_PAD_CTRL))
-#define MX53_PAD_SD2_DATA0__ESDHC2_DAT0		(_MX53_PAD_SD2_DATA0__ESDHC2_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__ESDHC2_DAT0		(_MX53_PAD_SD2_DATA0__ESDHC2_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
 #define MX53_PAD_SD2_DATA0__GPIO1_15		(_MX53_PAD_SD2_DATA0__GPIO1_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA0__KPP_ROW_7		(_MX53_PAD_SD2_DATA0__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
 #define MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD		(_MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/5] ARM: imx51/53: add sdhc3/4 clock
From: Richard Zhao @ 2011-02-21  9:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298282095-2279-1-git-send-email-richard.zhao@freescale.com>

Signed-off-by: Richard Zhao <richard.zhao@freescale.com>

diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 8164b1d..8ac61d5 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -42,6 +42,7 @@ static struct clk usboh3_clk;
 static struct clk emi_fast_clk;
 static struct clk ipu_clk;
 static struct clk mipi_hsc1_clk;
+static struct clk esdhc1_clk;
 
 #define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
 
@@ -1147,6 +1148,34 @@ CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
 CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
 CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
 
+static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CSCMR1);
+	if (parent == &esdhc1_clk)
+		reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+	else
+		reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+	__raw_writel(reg, MXC_CCM_CSCMR1);
+
+	return 0;
+}
+
+static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CSCMR1);
+	if (parent == &esdhc1_clk)
+		reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+	else
+		reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+	__raw_writel(reg, MXC_CCM_CSCMR1);
+
+	return 0;
+}
+
 #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s)		\
 	static struct clk name = {					\
 		.id		= i,					\
@@ -1253,6 +1282,32 @@ DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
 	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
 DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
 	clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
+	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
+	NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+
+static struct clk esdhc3_clk = {
+	.id = 2,
+	.parent = &esdhc1_clk,
+	.set_parent = clk_esdhc3_set_parent,
+	.enable_reg = MXC_CCM_CCGR3,
+	.enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+	.enable  = _clk_max_enable,
+	.disable = _clk_max_disable,
+	.secondary = &esdhc3_ipg_clk,
+};
+
+static struct clk esdhc4_clk = {
+	.id = 3,
+	.parent = &esdhc1_clk,
+	.set_parent = clk_esdhc4_set_parent,
+	.enable_reg = MXC_CCM_CCGR3,
+	.enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+	.enable  = _clk_max_enable,
+	.disable = _clk_max_disable,
+	.secondary = &esdhc4_ipg_clk,
+};
 
 DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
 DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
@@ -1312,6 +1367,8 @@ static struct clk_lookup mx51_lookups[] = {
 	_REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
 	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
 	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk)
 	_REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
 	_REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
 	_REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
@@ -1333,6 +1390,8 @@ static struct clk_lookup mx53_lookups[] = {
 	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
 	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
 	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk)
 	_REGISTER_CLOCK("imx53-ecspi.0", NULL, ecspi1_clk)
 	_REGISTER_CLOCK("imx53-ecspi.1", NULL, ecspi2_clk)
 	_REGISTER_CLOCK("imx53-cspi.0", NULL, cspi_clk)
@@ -1412,6 +1471,14 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
 	ckih2_reference = ckih2;
 	oscillator_reference = osc;
 
+	esdhc2_clk.get_rate = NULL;
+	esdhc2_clk.set_rate = NULL;
+	esdhc2_clk.set_parent = clk_esdhc3_set_parent;
+	esdhc2_clk.parent = &esdhc1_clk;
+	esdhc3_clk.get_rate = clk_esdhc2_get_rate;
+	esdhc3_clk.set_rate = clk_esdhc2_set_rate;
+	esdhc3_clk.set_parent = clk_esdhc2_set_parent;
+
 	for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
 		clkdev_add(&mx53_lookups[i]);
 
@@ -1425,6 +1492,14 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
 	mx53_revision();
 	clk_disable(&iim_clk);
 
+	/* Set SDHC parents to be PLL2 */
+	clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+	clk_set_parent(&esdhc3_clk, &pll2_sw_clk);
+
+	/* set SDHC root clock as 200MHZ*/
+	clk_set_rate(&esdhc1_clk, 200000000);
+	clk_set_rate(&esdhc3_clk, 200000000);
+
 	/* System timer */
 	mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
 		MX53_INT_GPT);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/5] ARM: imx53_loco: add esdhc device support
From: Richard Zhao @ 2011-02-21  9:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298282095-2279-1-git-send-email-richard.zhao@freescale.com>

Signed-off-by: Richard Zhao <richard.zhao@freescale.com>

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index f065a0d..a72c833 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -162,6 +162,7 @@ config MACH_MX53_LOCO
 	select IMX_HAVE_PLATFORM_IMX2_WDT
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	help
 	  Include support for MX53 LOCO platform. This includes specific
 	  configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 160899e..0a18f8d 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -213,6 +213,8 @@ static void __init mx53_loco_board_init(void)
 	imx53_add_imx2_wdt(0, NULL);
 	imx53_add_imx_i2c(0, &mx53_loco_i2c_data);
 	imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
+	imx53_add_sdhci_esdhc_imx(0, NULL);
+	imx53_add_sdhci_esdhc_imx(2, NULL);
 }
 
 static void __init mx53_loco_timer_init(void)
-- 
1.7.1

^ permalink raw reply related

* [PATCH 4/5] mm: sdhci-esdhc: remove SDHCI_QUIRK_NO_CARD_NO_RESET from ESDHC_DEFAULT_QUIRKS
From: Richard Zhao @ 2011-02-21  9:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298282095-2279-1-git-send-email-richard.zhao@freescale.com>

sdhci-esdhc-imx does not need SDHCI_QUIRK_NO_CARD_NO_RESET.
Make it OF-specific.

Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index afaf1bc..303cde0 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -24,8 +24,7 @@
 				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
 				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
-				SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \
-				SDHCI_QUIRK_NO_CARD_NO_RESET)
+				SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
 
 #define ESDHC_SYSTEM_CONTROL	0x2c
 #define ESDHC_CLOCK_MASK	0x0000fff0
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fcd0e1f..6337607 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -73,7 +73,7 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 }
 
 struct sdhci_of_data sdhci_esdhc = {
-	.quirks = ESDHC_DEFAULT_QUIRKS,
+	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_CARD_NO_RESET,
 	.ops = {
 		.read_l = sdhci_be32bs_readl,
 		.read_w = esdhc_readw,
-- 
1.7.1

^ permalink raw reply related

* [PATCH 5/5] mmc: sdhci: add quirk SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO
From: Richard Zhao @ 2011-02-21  9:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298282095-2279-1-git-send-email-richard.zhao@freescale.com>

Fix no INT in MULTI-BLK IO.

Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 9b82910..2eeb03e 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -113,7 +113,10 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
 	clk_enable(clk);
 	pltfm_host->clk = clk;
 
-	if (cpu_is_mx35() || cpu_is_mx51())
+	if (cpu_is_mx53())
+		host->quirks |= SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO;
+
+	if (cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx53())
 		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
 	/* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9e15f41..db7d0b7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -828,6 +828,20 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
 			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
 		else
 			mode |= SDHCI_TRNS_MULTI;
+
+		if (host->quirks & SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO) {
+			/*
+			 * Fix no INT bug in SDIO MULTI-BLK read
+			 * set bit1 of Vendor Spec Registor
+			 */
+			if ((host->cmd->opcode == 0x35)
+					&& (data->flags & MMC_DATA_READ)) {
+				u32 v;
+				v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+				v |= 0x2;
+				writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+			}
+		}
 	}
 	if (data->flags & MMC_DATA_READ)
 		mode |= SDHCI_TRNS_READ;
@@ -868,6 +882,12 @@ static void sdhci_finish_data(struct sdhci_host *host)
 	else
 		data->bytes_xfered = data->blksz * data->blocks;
 
+	if (host->quirks & SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO) {
+		if (readl(host->ioaddr + SDHCI_VENDOR_SPEC) & 0x2)
+			writel(readl(host->ioaddr + SDHCI_VENDOR_SPEC) & ~0x2,
+					host->ioaddr + SDHCI_VENDOR_SPEC);
+	}
+
 	if (data->stop) {
 		/*
 		 * The controller needs a reset of internal state machines
@@ -950,6 +970,11 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 	if (cmd->data)
 		flags |= SDHCI_CMD_DATA;
 
+	/*Set the CMD_TYPE of the CMD12, fix no INT in MULTI_BLK IO */
+	if (host->quirks & SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO) {
+		if (cmd->opcode == 12)
+			flags |= SDHCI_CMD_ABORTCMD;
+	}
 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
 }
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 6e0969e..1bd761f 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -45,6 +45,7 @@
 #define  SDHCI_CMD_CRC		0x08
 #define  SDHCI_CMD_INDEX	0x10
 #define  SDHCI_CMD_DATA		0x20
+#define  SDHCI_CMD_ABORTCMD	0xC0
 
 #define  SDHCI_CMD_RESP_NONE	0x00
 #define  SDHCI_CMD_RESP_LONG	0x01
@@ -183,6 +184,8 @@
 
 /* 60-FB reserved */
 
+#define SDHCI_VENDOR_SPEC	0xC0
+
 #define SDHCI_SLOT_INT_STATUS	0xFC
 
 #define SDHCI_HOST_VERSION	0xFE
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 83bd9f7..ae3c6de 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -85,6 +85,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_NO_HISPD_BIT			(1<<29)
 /* Controller treats ADMA descriptors with length 0000h incorrectly */
 #define SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC		(1<<30)
+/* Controller can't come to the correct status in MULTI-BLK IO automatically */
+#define SDHCI_QUIRK_FIX_NO_INT_IN_MULTI_BLK_IO		(1<<31)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/3] OMAP: smartreflex: move plat/smartreflex.h to mach-omap2/smartreflex.h
From: Cousson, Benoit @ 2011-02-21  9:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110221020851.7598.57763.stgit@twilight.localdomain>

Hi Paul,

On 2/21/2011 3:08 AM, Paul Walmsley wrote:
> There's no reason for this header file to be in
> plat-omap/include/plat/smartreflex.h.  The hardware devices are in
> OMAP2+ SoCs only.  Leaving this header file in plat-omap causes
> problems due to cross-dependencies with other header files that should
> live in mach-omap2/.
>
> Signed-off-by: Paul Walmsley<paul@pwsan.com>
> ---
>   arch/arm/mach-omap2/omap_hwmod_3xxx_data.c    |    2 +-
>   arch/arm/mach-omap2/smartreflex-class3.c      |    2 +-
>   arch/arm/mach-omap2/smartreflex.c             |    2 +-
>   arch/arm/mach-omap2/smartreflex.h             |    0
>   arch/arm/mach-omap2/sr_device.c               |    2 +-
>   5 files changed, 4 insertions(+), 4 deletions(-)
>   rename arch/arm/{plat-omap/include/plat/smartreflex.h =>  mach-omap2/smartreflex.h} (100%)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index 8d81813..7f0b5e7 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -21,13 +21,13 @@
>   #include<plat/l4_3xxx.h>
>   #include<plat/i2c.h>
>   #include<plat/gpio.h>
> -#include<plat/smartreflex.h>

In fact that include is not used for OMAP4 data and does not seems to be 
used either in this file.
I guess you can simply remove it.

Benoit

^ permalink raw reply

* [PATCH 01/09] ARM: s3c2442: gta02: Fix usage gpio bank j pin definitions
From: Kukjin Kim @ 2011-02-21  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D5E4CC1.1010705@metafoo.de>

Lasrs-Peter Clausen wrote:
> 
> On 02/07/2011 02:51 AM, Lars-Peter Clausen wrote:
> > The gta02 header file still uses the old S3C2410_GPJx defines instead of
> the
> > S3C2410_GPJ(x) macro. Since the S3C2410_GPJx defines have already been
> removed
> > this causes the following build failure:
> >
> > 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_set_spk':
> > 	sound/soc/samsung/neo1973_wm8753.c:259: error: 'S3C2440_GPJ2'
> undeclared (first use in this function)
> > 	sound/soc/samsung/neo1973_wm8753.c:259: error: (Each undeclared
> identifier is reported only once
> > 	sound/soc/samsung/neo1973_wm8753.c:259: error: for each function it
> appears in.)
> > 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_get_spk':
> > 	sound/soc/samsung/neo1973_wm8753.c:267: error: 'S3C2440_GPJ2'
> undeclared (first use in this function)
> > 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_event':
> > 	sound/soc/samsung/neo1973_wm8753.c:276: error: 'S3C2440_GPJ1'
> undeclared (first use in this function)
> > 	sound/soc/samsung/neo1973_wm8753.c: At top level:
> > 	sound/soc/samsung/neo1973_wm8753.c:439: error: 'S3C2440_GPJ2'
> undeclared here (not in a function)
> > 	sound/soc/samsung/neo1973_wm8753.c:440: error: 'S3C2440_GPJ1'
> undeclared here (not in a function)
> >
> > This patches fixes the issue by doing a
> s,S3C2410_GPJ([\d]+),S3C2410_GPJ(\1),g
> > on the file.
> >
> > Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> 
> 
> Hi
> 
> Ben or Kukjin could you take a look at this series and merge it, if it is
ok?
> 
Hi Lars-Peter,

Basically, the maintainer of mach-s3c* is Ben Dooks.
I think, he will review this series but if he can't soon, I will/can do it.

Ben, could you please review this patches?
If you're busy, please let me know :)

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
From: Kukjin Kim @ 2011-02-21  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110220120039.GA14495@n2100.arm.linux.org.uk>

Russell King - ARM Linux wrote:
> 
> Kukjin, could you test this update as well please?
> 
No problem :)

It works fine with following.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

> Thanks.
> 
> On Tue, Feb 15, 2011 at 11:04:53AM +0000, Russell King - ARM Linux wrote:
> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > > > +ENDPROC(cpu_resume_turn_mmu_on)
> > > > +cpu_resume_after_mmu:
> > > > + ? ? ? str ? ? r5, [r2, r4, lsl #2] ? ?@ restore old mapping
> > > > +#ifdef MULTI_CACHE
> > > > + ? ? ? ldr ? ? r10, =cpu_cache
> > > > + ? ? ? ldr ? ? pc, [r10, #CACHE_FLUSH_KERN_ALL]
> > > > +#else
> > > > + ? ? ? b ? ? ? __cpuc_flush_kern_all
> > > > +#endif
> >
> > I think we can eliminate this cache flush by delaying the cache enable
> > as below.  Could you see whether Tegra 2 survives this please?
> > Thanks.
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index bed1876..193be5f 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -4,6 +4,7 @@
> >  #include <asm/assembler.h>
> >  #include <asm/glue-cache.h>
> >  #include <asm/glue-proc.h>
> > +#include <asm/system.h>
> >  	.text
> >
> >  /*
> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> >  	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
> >  	sub	r2, r2, r1
> >  	ldr	r3, =cpu_resume_after_mmu
> > +	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
> >  	b	cpu_resume_turn_mmu_on
> >  ENDPROC(cpu_resume_mmu)
> >  	.ltorg
> >  	.align	5
> >  cpu_resume_turn_mmu_on:
> > -	mcr	p15, 0, r0, c1, c0, 0	@ turn on MMU, caches, etc
> > -	mrc	p15, 0, r0, c0, c0, 0	@ read id reg
> > -	mov	r0, r0
> > -	mov	r0, r0
> > +	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
> > +	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
> > +	mov	r1, r1
> > +	mov	r1, r1
> >  	mov	pc, r3			@ jump to virtual address
> >  ENDPROC(cpu_resume_turn_mmu_on)
> >  cpu_resume_after_mmu:
> >  	str	r5, [r2, r4, lsl #2]	@ restore old mapping
> > -#ifdef MULTI_CACHE
> > -	ldr	r10, =cpu_cache
> > -	ldr	pc, [r10, #CACHE_FLUSH_KERN_ALL]
> > -#else
> > -	b	__cpuc_flush_kern_all
> > -#endif
> > +	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
> > +	mov	pc, lr
> >
> >  /*
> >   * Note: Yes, part of the following code is located into the .data
section.

^ permalink raw reply

* [GIT PULL] Samsung fixes for 2.6.38-rc6
From: Kukjin Kim @ 2011-02-21  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

Please pull Samsung fixes from:

git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
s5p-fixes-for-linus

These things are for small fix and cleanup on 2.6.38-rc6.
As a note, cleanup patch includes fixing coding style such as removing
useless braces, and re-ordering.

If any problems, please let me know.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

The following changes since commit 85e2efbb1db9a18d218006706d6e4fbeb0216213:

  Linux 2.6.38-rc5 (2011-02-15 19:23:45 -0800)

are available in the git repository at:
   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
s5p-fixes-for-linus

Axel Lin (1):
      ARM: SAMSUNG: Drop exporting s3c24xx_ts_set_platdata

Kukjin Kim (5):
      ARM: S5PV310: Cleanup map.h file
      ARM: S5PV210: Cleanup map.h file
      ARM: S5PC100: Clenaup map.h file
      ARM: S5P6442: Cleanup map.h file
      ARM: S5P64X0: Cleanup map.h file

Marek Szyprowski (2):
      ARM: S5PV210: Update max8998_platform_data
      ARM: S5PV210: Fix regulator names

Thomas Abraham (1):
      ARM: S5P: Fix end address in memory resource information for UART
devices

 arch/arm/mach-s5p6442/include/mach/map.h |   69 ++++++-----
 arch/arm/mach-s5p64x0/include/mach/map.h |   83 +++++++-------
 arch/arm/mach-s5pc100/include/mach/map.h |  193
+++++++++++++-----------------
 arch/arm/mach-s5pv210/include/mach/map.h |  168 +++++++++++++-------------
 arch/arm/mach-s5pv210/mach-aquila.c      |   15 ++-
 arch/arm/mach-s5pv210/mach-goni.c        |   15 ++-
 arch/arm/mach-s5pv310/include/mach/map.h |  149 +++++++++++------------
 arch/arm/plat-s5p/dev-uart.c             |   12 +-
 arch/arm/plat-samsung/dev-ts.c           |    1 -
 9 files changed, 342 insertions(+), 363 deletions(-)

^ 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