1. 09 7月, 2018 1 次提交
  2. 14 6月, 2018 1 次提交
    • R
      PM / core: Fix supplier device runtime PM usage counter imbalance · 47e5abfb
      Rafael J. Wysocki 提交于
      If a device link is added via device_link_add() by the driver of the
      link's consumer device, the supplier's runtime PM usage counter is
      going to be dropped by the pm_runtime_put_suppliers() call in
      driver_probe_device().  However, in that case it is not incremented
      unless the supplier driver is already present and the link is not
      stateless.  That leads to a runtime PM usage counter imbalance for
      the supplier device in a few cases.
      
      To prevent that from happening, bump up the supplier runtime
      PM usage counter in device_link_add() for all links with the
      DL_FLAG_PM_RUNTIME flag set that are added at the consumer probe
      time.  Use pm_runtime_get_noresume() for that as the callers of
      device_link_add() who want the supplier to be resumed by it are
      expected to pass DL_FLAG_RPM_ACTIVE in flags to it anyway, but
      additionally resume the supplier if the link is added during
      consumer driver probe to retain the existing behavior for the
      callers depending on it.
      
      Fixes: 21d5c57b (PM / runtime: Use device links)
      Reported-by: NUlf Hansson <ulf.hansson@linaro.org>
      Reviewed-by: NUlf Hansson <ulf.hansson@linaro.org>
      Tested-by: NMarek Szyprowski <m.szyprowski@samsung.com>
      Cc: 4.10+ <stable@vger.kernel.org> # 4.10+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      47e5abfb
  3. 14 5月, 2018 3 次提交
  4. 24 4月, 2018 1 次提交
  5. 28 2月, 2018 1 次提交
    • L
      driver core: Introduce device links reference counting · ead18c23
      Lukas Wunner 提交于
      If device_link_add() is invoked multiple times with the same supplier
      and consumer combo, it will create the link on first addition and
      return a pointer to the already existing link on all subsequent
      additions.
      
      The semantics for device_link_del() are quite different, it deletes
      the link unconditionally, so multiple invocations are not allowed.
      
      In other words, this snippet ...
      
          struct device *dev1, *dev2;
          struct device_link *link1, *link2;
      
          link1 = device_link_add(dev1, dev2, 0);
          link2 = device_link_add(dev1, dev2, 0);
      
          device_link_del(link1);
          device_link_del(link2);
      
      ... causes the following crash:
      
          WARNING: CPU: 4 PID: 2686 at drivers/base/power/runtime.c:1611 pm_runtime_drop_link+0x40/0x50
          [...]
          list_del corruption, 0000000039b800a4->prev is LIST_POISON2 (00000000ecf79852)
          kernel BUG at lib/list_debug.c:50!
      
      The issue isn't as arbitrary as it may seem:  Imagine a device link
      which is added in both the supplier's and the consumer's ->probe hook.
      The two drivers can't just call device_link_del() in their ->remove hook
      without coordination.
      
      Fix by counting multiple additions and dropping the device link only
      when the last addition is unwound.
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      [ rjw: Subject ]
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      ead18c23
  6. 12 2月, 2018 1 次提交
  7. 05 1月, 2018 1 次提交
    • S
      drivers: do not use print_symbol() · a52668c6
      Sergey Senozhatsky 提交于
      print_symbol() is a very old API that has been obsoleted by %pS format
      specifier in a normal printk() call.
      
      Replace print_symbol() with a direct printk("%pS") call.
      
      Link: http://lkml.kernel.org/r/20171211125025.2270-10-sergey.senozhatsky@gmail.com
      To: Andrew Morton <akpm@linux-foundation.org>
      To: Russell King <linux@armlinux.org.uk>
      To: Catalin Marinas <catalin.marinas@arm.com>
      To: Mark Salter <msalter@redhat.com>
      To: Tony Luck <tony.luck@intel.com>
      To: David Howells <dhowells@redhat.com>
      To: Yoshinori Sato <ysato@users.sourceforge.jp>
      To: Guan Xuetao <gxt@mprc.pku.edu.cn>
      To: Borislav Petkov <bp@alien8.de>
      To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      To: Thomas Gleixner <tglx@linutronix.de>
      To: Peter Zijlstra <peterz@infradead.org>
      To: Vineet Gupta <vgupta@synopsys.com>
      To: Fengguang Wu <fengguang.wu@intel.com>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Petr Mladek <pmladek@suse.com>
      Cc: LKML <linux-kernel@vger.kernel.org>
      Cc: linux-arm-kernel@lists.infradead.org
      Cc: linux-c6x-dev@linux-c6x.org
      Cc: linux-ia64@vger.kernel.org
      Cc: linux-am33-list@redhat.com
      Cc: linux-sh@vger.kernel.org
      Cc: linux-edac@vger.kernel.org
      Cc: x86@kernel.org
      Cc: linux-snps-arc@lists.infradead.org
      Signed-off-by: NSergey Senozhatsky <sergey.senozhatsky@gmail.com>
      [pmladek@suse.com: updated commit message]
      Signed-off-by: NPetr Mladek <pmladek@suse.com>
      a52668c6
  8. 18 12月, 2017 1 次提交
  9. 08 12月, 2017 2 次提交
    • G
      driver core: Remove redundant license text · 32825709
      Greg Kroah-Hartman 提交于
      Now that the SPDX tag is in all driver core files, that identifies the
      license in a specific and legally-defined manner.  So the extra GPL text
      wording can be removed as it is no longer needed at all.
      
      This is done on a quest to remove the 700+ different ways that files in
      the kernel describe the GPL license text.  And there's unneeded stuff
      like the address (sometimes incorrect) for the FSF which is never
      needed.
      
      No copyright headers or other non-license-description text was removed.
      
      Cc: Johannes Berg <johannes@sipsolutions.net>
      Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      32825709
    • G
      driver core: add SPDX identifiers to all driver core files · 989d42e8
      Greg Kroah-Hartman 提交于
      It's good to have SPDX identifiers in all files to make it easier to
      audit the kernel tree for correct licenses.
      
      Update the driver core files files with the correct SPDX license
      identifier based on the license text in the file itself.  The SPDX
      identifier is a legally binding shorthand, which can be used instead of
      the full boiler plate text.
      
      This work is based on a script and data from Thomas Gleixner, Philippe
      Ombredanne, and Kate Stewart.
      
      Cc: Johannes Berg <johannes@sipsolutions.net>
      Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
      Cc: William Breathitt Gray <vilhelm.gray@gmail.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Kate Stewart <kstewart@linuxfoundation.org>
      Cc: Philippe Ombredanne <pombredanne@nexb.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      989d42e8
  10. 25 10月, 2017 1 次提交
    • M
      locking/atomics: COCCINELLE/treewide: Convert trivial ACCESS_ONCE() patterns... · 6aa7de05
      Mark Rutland 提交于
      locking/atomics: COCCINELLE/treewide: Convert trivial ACCESS_ONCE() patterns to READ_ONCE()/WRITE_ONCE()
      
      Please do not apply this to mainline directly, instead please re-run the
      coccinelle script shown below and apply its output.
      
      For several reasons, it is desirable to use {READ,WRITE}_ONCE() in
      preference to ACCESS_ONCE(), and new code is expected to use one of the
      former. So far, there's been no reason to change most existing uses of
      ACCESS_ONCE(), as these aren't harmful, and changing them results in
      churn.
      
      However, for some features, the read/write distinction is critical to
      correct operation. To distinguish these cases, separate read/write
      accessors must be used. This patch migrates (most) remaining
      ACCESS_ONCE() instances to {READ,WRITE}_ONCE(), using the following
      coccinelle script:
      
      ----
      // Convert trivial ACCESS_ONCE() uses to equivalent READ_ONCE() and
      // WRITE_ONCE()
      
      // $ make coccicheck COCCI=/home/mark/once.cocci SPFLAGS="--include-headers" MODE=patch
      
      virtual patch
      
      @ depends on patch @
      expression E1, E2;
      @@
      
      - ACCESS_ONCE(E1) = E2
      + WRITE_ONCE(E1, E2)
      
      @ depends on patch @
      expression E;
      @@
      
      - ACCESS_ONCE(E)
      + READ_ONCE(E)
      ----
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Signed-off-by: NPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: davem@davemloft.net
      Cc: linux-arch@vger.kernel.org
      Cc: mpe@ellerman.id.au
      Cc: shuah@kernel.org
      Cc: snitzer@redhat.com
      Cc: thor.thayer@linux.intel.com
      Cc: tj@kernel.org
      Cc: viro@zeniv.linux.org.uk
      Cc: will.deacon@arm.com
      Link: http://lkml.kernel.org/r/1508792849-3115-19-git-send-email-paulmck@linux.vnet.ibm.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
      6aa7de05
  11. 20 10月, 2017 1 次提交
  12. 17 10月, 2017 1 次提交
  13. 29 8月, 2017 1 次提交
  14. 22 7月, 2017 2 次提交
  15. 07 7月, 2017 1 次提交
  16. 13 6月, 2017 1 次提交
    • J
      driver core: add helper to reuse a device-tree node · 4e75e1d7
      Johan Hovold 提交于
      Add a helper function to be used when reusing the device-tree node of
      another device.
      
      It is fairly common for drivers to reuse the device-tree node of a
      parent (or other ancestor) device when creating class or bus devices
      (e.g. gpio chips, i2c adapters, iio chips, spi masters, serdev, phys,
      usb root hubs). But reusing a device-tree node may cause problems if the
      new device is later probed as for example driver core would currently
      attempt to reinitialise an already active associated pinmux
      configuration.
      
      Other potential issues include the platform-bus code unconditionally
      dropping the device-tree node reference in its device destructor,
      reinitialisation of other bus-managed resources such as clocks, and the
      recently added DMA-setup in driver core.
      
      Note that for most examples above this is currently not an issue as the
      devices are never probed, but this is a problem for the USB bus which
      has recently gained device-tree support. This was discovered and
      worked-around in a rather ad-hoc fashion by commit dc5878ab ("usb:
      core: move root hub's device node assignment after it is added to bus")
      by not setting the of_node pointer until after the root-hub device has
      been registered.
      
      Instead we can allow devices to reuse a device-tree node by setting a
      flag in their struct device that can be used by core, bus and driver
      code to avoid resources from being over-allocated.
      
      Note that the helper also grabs an extra reference to the device node,
      which specifically balances the unconditional put in the platform-device
      destructor.
      Signed-off-by: NJohan Hovold <johan@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4e75e1d7
  17. 26 5月, 2017 1 次提交
    • P
      kobject: support passing in variables for synthetic uevents · f36776fa
      Peter Rajnoha 提交于
      This patch makes it possible to pass additional arguments in addition
      to uevent action name when writing /sys/.../uevent attribute. These
      additional arguments are then inserted into generated synthetic uevent
      as additional environment variables.
      
      Before, we were not able to pass any additional uevent environment
      variables for synthetic uevents. This made it hard to identify such uevents
      properly in userspace to make proper distinction between genuine uevents
      originating from kernel and synthetic uevents triggered from userspace.
      Also, it was not possible to pass any additional information which would
      make it possible to optimize and change the way the synthetic uevents are
      processed back in userspace based on the originating environment of the
      triggering action in userspace. With the extra additional variables, we are
      able to pass through this extra information needed and also it makes it
      possible to synchronize with such synthetic uevents as they can be clearly
      identified back in userspace.
      
      The format for writing the uevent attribute is following:
      
          ACTION [UUID [KEY=VALUE ...]
      
      There's no change in how "ACTION" is recognized - it stays the same
      ("add", "change", "remove"). The "ACTION" is the only argument required
      to generate synthetic uevent, the rest of arguments, that this patch
      adds support for, are optional.
      
      The "UUID" is considered as transaction identifier so it's possible to
      use the same UUID value for one or more synthetic uevents in which case
      we logically group these uevents together for any userspace listeners.
      The "UUID" is expected to be in "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      format where "x" is a hex digit. The value appears in uevent as
      "SYNTH_UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" environment variable.
      
      The "KEY=VALUE" pairs can contain alphanumeric characters only. It's
      possible to define zero or more more pairs - each pair is then delimited
      by a space character " ". Each pair appears in synthetic uevents as
      "SYNTH_ARG_KEY=VALUE" environment variable. That means the KEY name gains
      "SYNTH_ARG_" prefix to avoid possible collisions with existing variables.
      To pass the "KEY=VALUE" pairs, it's also required to pass in the "UUID"
      part for the synthetic uevent first.
      
      If "UUID" is not passed in, the generated synthetic uevent gains
      "SYNTH_UUID=0" environment variable automatically so it's possible to
      identify this situation in userspace when reading generated uevent and so
      we can still make a difference between genuine and synthetic uevents.
      Signed-off-by: NPeter Rajnoha <prajnoha@redhat.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f36776fa
  18. 09 4月, 2017 1 次提交
  19. 17 3月, 2017 1 次提交
  20. 02 3月, 2017 1 次提交
  21. 25 2月, 2017 1 次提交
  22. 14 1月, 2017 1 次提交
  23. 05 12月, 2016 1 次提交
  24. 11 11月, 2016 1 次提交
  25. 01 11月, 2016 3 次提交
    • R
      PM / runtime: Optimize the use of device links · baa8809f
      Rafael J. Wysocki 提交于
      If the device has no links to suppliers that should be used for
      runtime PM (links with DEVICE_LINK_PM_RUNTIME set), there is no
      reason to walk the list of suppliers for that device during
      runtime suspend and resume.
      
      Add a simple mechanism to detect that case and possibly avoid the
      extra unnecessary overhead.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      baa8809f
    • R
      PM / runtime: Use device links · 21d5c57b
      Rafael J. Wysocki 提交于
      Modify the runtime PM framework to use device links to ensure that
      supplier devices will not be suspended if any of their consumer
      devices are active.
      
      The idea is to reference count suppliers on the consumer's resume
      and drop references to them on its suspend.  The information on
      whether or not the supplier has been reference counted by the
      consumer's (runtime) resume is stored in a new field (rpm_active)
      in the link object for each link.
      
      It may be necessary to clean up those references when the
      supplier is unbinding and that's why the links whose status is
      DEVICE_LINK_SUPPLIER_UNBIND are skipped by the runtime suspend
      and resume code.
      
      The above means that if the consumer device is probed in the
      runtime-active state, the supplier has to be resumed and reference
      counted by device_link_add() so the code works as expected on its
      (runtime) suspend.  There is a new flag, DEVICE_LINK_RPM_ACTIVE,
      to tell device_link_add() about that (in which case the caller
      is responsible for making sure that the consumer really will
      be runtime-active when runtime PM is enabled for it).
      
      The other new link flag, DEVICE_LINK_PM_RUNTIME, tells the core
      whether or not the link should be used for runtime PM at all.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      21d5c57b
    • R
      driver core: Functional dependencies tracking support · 9ed98953
      Rafael J. Wysocki 提交于
      Currently, there is a problem with taking functional dependencies
      between devices into account.
      
      What I mean by a "functional dependency" is when the driver of device
      B needs device A to be functional and (generally) its driver to be
      present in order to work properly.  This has certain consequences
      for power management (suspend/resume and runtime PM ordering) and
      shutdown ordering of these devices.  In general, it also implies that
      the driver of A needs to be working for B to be probed successfully
      and it cannot be unbound from the device before the B's driver.
      
      Support for representing those functional dependencies between
      devices is added here to allow the driver core to track them and act
      on them in certain cases where applicable.
      
      The argument for doing that in the driver core is that there are
      quite a few distinct use cases involving device dependencies, they
      are relatively hard to get right in a driver (if one wants to
      address all of them properly) and it only gets worse if multiplied
      by the number of drivers potentially needing to do it.  Morever, at
      least one case (asynchronous system suspend/resume) cannot be handled
      in a single driver at all, because it requires the driver of A to
      wait for B to suspend (during system suspend) and the driver of B to
      wait for A to resume (during system resume).
      
      For this reason, represent dependencies between devices as "links",
      with the help of struct device_link objects each containing pointers
      to the "linked" devices, a list node for each of them, status
      information, flags, and an RCU head for synchronization.
      
      Also add two new list heads, representing the lists of links to the
      devices that depend on the given one (consumers) and to the devices
      depended on by it (suppliers), and a "driver presence status" field
      (needed for figuring out initial states of device links) to struct
      device.
      
      The entire data structure consisting of all of the lists of link
      objects for all devices is protected by a mutex (for link object
      addition/removal and for list walks during device driver probing
      and removal) and by SRCU (for list walking in other case that will
      be introduced by subsequent change sets).  If CONFIG_SRCU is not
      selected, however, an rwsem is used for protecting the entire data
      structure.
      
      In addition, each link object has an internal status field whose
      value reflects whether or not drivers are bound to the devices
      pointed to by the link or probing/removal of their drivers is in
      progress etc.  That field is only modified under the device links
      mutex, but it may be read outside of it in some cases (introduced by
      subsequent change sets), so modifications of it are annotated with
      WRITE_ONCE().
      
      New links are added by calling device_link_add() which takes three
      arguments: pointers to the devices in question and flags.  In
      particular, if DL_FLAG_STATELESS is set in the flags, the link status
      is not to be taken into account for this link and the driver core
      will not manage it.  In turn, if DL_FLAG_AUTOREMOVE is set in the
      flags, the driver core will remove the link automatically when the
      consumer device driver unbinds from it.
      
      One of the actions carried out by device_link_add() is to reorder
      the lists used for device shutdown and system suspend/resume to
      put the consumer device along with all of its children and all of
      its consumers (and so on, recursively) to the ends of those lists
      in order to ensure the right ordering between all of the supplier
      and consumer devices.
      
      For this reason, it is not possible to create a link between two
      devices if the would-be supplier device already depends on the
      would-be consumer device as either a direct descendant of it or a
      consumer of one of its direct descendants or one of its consumers
      and so on.
      
      There are two types of link objects, persistent and non-persistent.
      The persistent ones stay around until one of the target devices is
      deleted, while the non-persistent ones are removed automatically when
      the consumer driver unbinds from its device (ie. they are assumed to
      be valid only as long as the consumer device has a driver bound to
      it).  Persistent links are created by default and non-persistent
      links are created when the DL_FLAG_AUTOREMOVE flag is passed
      to device_link_add().
      
      Both persistent and non-persistent device links can be deleted
      with an explicit call to device_link_del().
      
      Links created without the DL_FLAG_STATELESS flag set are managed
      by the driver core using a simple state machine.  There are 5 states
      each link can be in: DORMANT (unused), AVAILABLE (the supplier driver
      is present and functional), CONSUMER_PROBE (the consumer driver is
      probing), ACTIVE (both supplier and consumer drivers are present and
      functional), and SUPPLIER_UNBIND (the supplier driver is unbinding).
      The driver core updates the link state automatically depending on
      what happens to the linked devices and for each link state specific
      actions are taken in addition to that.
      
      For example, if the supplier driver unbinds from its device, the
      driver core will also unbind the drivers of all of its consumers
      automatically under the assumption that they cannot function
      properly without the supplier.  Analogously, the driver core will
      only allow the consumer driver to bind to its device if the
      supplier driver is present and functional (ie. the link is in
      the AVAILABLE state).  If that's not the case, it will rely on
      the existing deferred probing mechanism to wait for the supplier
      driver to become available.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9ed98953
  26. 31 8月, 2016 2 次提交
  27. 07 12月, 2015 1 次提交
  28. 18 10月, 2015 1 次提交
  29. 18 9月, 2015 1 次提交
  30. 06 8月, 2015 1 次提交
    • G
      driver core: correct device's shutdown order · 52cdbdd4
      Grygorii Strashko 提交于
      Now device's shutdown sequence is performed in reverse order of their
      registration in devices_kset list and this sequence corresponds to the
      reverse device's creation order. So, devices_kset data tracks
      "parent<-child" device's dependencies only.
      
      Unfortunately, that's not enough and causes problems in case of
      implementing board's specific shutdown procedures. For example [1]:
      "DRA7XX_evm uses PCF8575 and one of the PCF output lines feeds to
      MMC/SD and this line should be driven high in order for the MMC/SD to
      be detected. This line is modelled as regulator and the hsmmc driver
      takes care of enabling and disabling it. In the case of 'reboot',
      during shutdown path as part of it's cleanup process the hsmmc driver
      disables this regulator. This makes MMC boot not functional."
      
      To handle this issue the .shutdown() callback could be implemented
      for PCF8575 device where corresponding GPIO pins will be configured to
      states, required for correct warm/cold reset. This can be achieved
      only when all .shutdown() callbacks have been called already for all
      PCF8575's consumers. But devices_kset is not filled correctly now:
      
      devices_kset: Device61 4e000000.dmm
      devices_kset: Device62 48070000.i2c
      devices_kset: Device63 48072000.i2c
      devices_kset: Device64 48060000.i2c
      devices_kset: Device65 4809c000.mmc
      ...
      devices_kset: Device102 fixedregulator-sd
      ...
      devices_kset: Device181 0-0020 // PCF8575
      devices_kset: Device182 gpiochip496
      devices_kset: Device183 0-0021 // PCF8575
      devices_kset: Device184 gpiochip480
      
      As can be seen from above .shutdown() callback for PCF8575 will be called
      before its consumers, which, in turn means, that any changes of PCF8575
      GPIO's pins will be or unsafe or overwritten later by GPIO's consumers.
      The problem can be solved if devices_kset list will be filled not only
      according device creation order, but also according device's probing
      order to track "supplier<-consumer" dependencies also.
      
      Hence, as a fix, lets add devices_kset_move_last(),
      devices_kset_move_before(), devices_kset_move_after() and call them
      from device_move() and also add call of devices_kset_move_last() in
      really_probe(). After this change all entries in devices_kset will
      be sorted according to device's creation ("parent<-child") and
      probing ("supplier<-consumer") order.
      
      devices_kset after:
      devices_kset: Device121 48070000.i2c
      devices_kset: Device122 i2c-0
      ...
      devices_kset: Device147 regulator.24
      devices_kset: Device148 0-0020
      devices_kset: Device149 gpiochip496
      devices_kset: Device150 0-0021
      devices_kset: Device151 gpiochip480
      devices_kset: Device152 0-0019
      ...
      devices_kset: Device372 fixedregulator-sd
      devices_kset: Device373 regulator.29
      devices_kset: Device374 4809c000.mmc
      devices_kset: Device375 mmc0
      
      [1] http://www.spinics.net/lists/linux-mmc/msg29825.html
      
      Cc: Sekhar Nori <nsekhar@ti.com>
      Signed-off-by: NGrygorii Strashko <grygorii.strashko@ti.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      52cdbdd4
  31. 28 7月, 2015 1 次提交
  32. 23 7月, 2015 1 次提交
  33. 26 6月, 2015 1 次提交