History

firmware: ti_sci: Add support for IRQ management

TISCI abstracts the handling of IRQ routes where interrupt sources are not directly connected to host interrupt controller. Add support for the set of TISCI commands for requesting and releasing IRQs.

Lokesh Vutla committed 7 years ago

Commit 997b0011 parent 9c19fb63 files · +331 −0Browse files

Unified · Split

3 files
  1. drivers/firmware/ti_sci.c +245 −0
  2. drivers/firmware/ti_sci.h +60 −0
  3. include/linux/soc/ti/ti_sci_protocol.h +26 −0
drivers/firmware/ti_sci.c+245−0
@@ -1765,6 +1765,245 @@ int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle, · 1764 unmodified lines
1765 range_start, range_num);1765 range_start, range_num);
1766}1766}
1767 1767
1768/**
1769 * ti_sci_manage_irq() - Helper api to configure/release the irq route between
1770 * the requested source and destination
1771 * @handle: Pointer to TISCI handle.
1772 * @valid_params: Bit fields defining the validity of certain params
1773 * @src_id: Device ID of the IRQ source
1774 * @src_index: IRQ source index within the source device
1775 * @dst_id: Device ID of the IRQ destination
1776 * @dst_host_irq: IRQ number of the destination device
1777 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1778 * @vint: Virtual interrupt to be used within the IA
1779 * @global_event: Global event number to be used for the requesting event
1780 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1781 * @s_host: Secondary host ID to which the irq/event is being
1782 * requested for.
1783 * @type: Request type irq set or release.
1784 *
1785 * Return: 0 if all went fine, else return appropriate error.
1786 */
1787static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
1788 u32 valid_params, u16 src_id, u16 src_index,
1789 u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
1790 u16 global_event, u8 vint_status_bit, u8 s_host,
1791 u16 type)
1792{
1793 struct ti_sci_msg_req_manage_irq *req;
1794 struct ti_sci_msg_hdr *resp;
1795 struct ti_sci_xfer *xfer;
1796 struct ti_sci_info *info;
1797 struct device *dev;
1798 int ret = 0;
1799
1800 if (IS_ERR(handle))
1801 return PTR_ERR(handle);
1802 if (!handle)
1803 return -EINVAL;
1804
1805 info = handle_to_ti_sci_info(handle);
1806 dev = info->dev;
1807
1808 xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1809 sizeof(*req), sizeof(*resp));
1810 if (IS_ERR(xfer)) {
1811 ret = PTR_ERR(xfer);
1812 dev_err(dev, "Message alloc failed(%d)\n", ret);
1813 return ret;
1814 }
1815 req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
1816 req->valid_params = valid_params;
1817 req->src_id = src_id;
1818 req->src_index = src_index;
1819 req->dst_id = dst_id;
1820 req->dst_host_irq = dst_host_irq;
1821 req->ia_id = ia_id;
1822 req->vint = vint;
1823 req->global_event = global_event;
1824 req->vint_status_bit = vint_status_bit;
1825 req->secondary_host = s_host;
1826
1827 ret = ti_sci_do_xfer(info, xfer);
1828 if (ret) {
1829 dev_err(dev, "Mbox send fail %d\n", ret);
1830 goto fail;
1831 }
1832
1833 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1834
1835 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1836
1837fail:
1838 ti_sci_put_one_xfer(&info->minfo, xfer);
1839
1840 return ret;
1841}
1842
1843/**
1844 * ti_sci_set_irq() - Helper api to configure the irq route between the
1845 * requested source and destination
1846 * @handle: Pointer to TISCI handle.
1847 * @valid_params: Bit fields defining the validity of certain params
1848 * @src_id: Device ID of the IRQ source
1849 * @src_index: IRQ source index within the source device
1850 * @dst_id: Device ID of the IRQ destination
1851 * @dst_host_irq: IRQ number of the destination device
1852 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1853 * @vint: Virtual interrupt to be used within the IA
1854 * @global_event: Global event number to be used for the requesting event
1855 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1856 * @s_host: Secondary host ID to which the irq/event is being
1857 * requested for.
1858 *
1859 * Return: 0 if all went fine, else return appropriate error.
1860 */
1861static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
1862 u16 src_id, u16 src_index, u16 dst_id,
1863 u16 dst_host_irq, u16 ia_id, u16 vint,
1864 u16 global_event, u8 vint_status_bit, u8 s_host)
1865{
1866 pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
1867 __func__, valid_params, src_id, src_index,
1868 dst_id, dst_host_irq, ia_id, vint, global_event,
1869 vint_status_bit);
1870
1871 return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
1872 dst_id, dst_host_irq, ia_id, vint,
1873 global_event, vint_status_bit, s_host,
1874 TI_SCI_MSG_SET_IRQ);
1875}
1876
1877/**
1878 * ti_sci_free_irq() - Helper api to free the irq route between the
1879 * requested source and destination
1880 * @handle: Pointer to TISCI handle.
1881 * @valid_params: Bit fields defining the validity of certain params
1882 * @src_id: Device ID of the IRQ source
1883 * @src_index: IRQ source index within the source device
1884 * @dst_id: Device ID of the IRQ destination
1885 * @dst_host_irq: IRQ number of the destination device
1886 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1887 * @vint: Virtual interrupt to be used within the IA
1888 * @global_event: Global event number to be used for the requesting event
1889 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1890 * @s_host: Secondary host ID to which the irq/event is being
1891 * requested for.
1892 *
1893 * Return: 0 if all went fine, else return appropriate error.
1894 */
1895static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
1896 u16 src_id, u16 src_index, u16 dst_id,
1897 u16 dst_host_irq, u16 ia_id, u16 vint,
1898 u16 global_event, u8 vint_status_bit, u8 s_host)
1899{
1900 pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
1901 __func__, valid_params, src_id, src_index,
1902 dst_id, dst_host_irq, ia_id, vint, global_event,
1903 vint_status_bit);
1904
1905 return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
1906 dst_id, dst_host_irq, ia_id, vint,
1907 global_event, vint_status_bit, s_host,
1908 TI_SCI_MSG_FREE_IRQ);
1909}
1910
1911/**
1912 * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
1913 * source and destination.
1914 * @handle: Pointer to TISCI handle.
1915 * @src_id: Device ID of the IRQ source
1916 * @src_index: IRQ source index within the source device
1917 * @dst_id: Device ID of the IRQ destination
1918 * @dst_host_irq: IRQ number of the destination device
1919 * @vint_irq: Boolean specifying if this interrupt belongs to
1920 * Interrupt Aggregator.
1921 *
1922 * Return: 0 if all went fine, else return appropriate error.
1923 */
1924static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
1925 u16 src_index, u16 dst_id, u16 dst_host_irq)
1926{
1927 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
1928
1929 return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id,
1930 dst_host_irq, 0, 0, 0, 0, 0);
1931}
1932
1933/**
1934 * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
1935 * requested source and Interrupt Aggregator.
1936 * @handle: Pointer to TISCI handle.
1937 * @src_id: Device ID of the IRQ source
1938 * @src_index: IRQ source index within the source device
1939 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1940 * @vint: Virtual interrupt to be used within the IA
1941 * @global_event: Global event number to be used for the requesting event
1942 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1943 *
1944 * Return: 0 if all went fine, else return appropriate error.
1945 */
1946static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
1947 u16 src_id, u16 src_index, u16 ia_id,
1948 u16 vint, u16 global_event,
1949 u8 vint_status_bit)
1950{
1951 u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
1952 MSG_FLAG_GLB_EVNT_VALID |
1953 MSG_FLAG_VINT_STS_BIT_VALID;
1954
1955 return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
1956 ia_id, vint, global_event, vint_status_bit, 0);
1957}
1958
1959/**
1960 * ti_sci_cmd_free_irq() - Free a host irq route between the between the
1961 * requested source and destination.
1962 * @handle: Pointer to TISCI handle.
1963 * @src_id: Device ID of the IRQ source
1964 * @src_index: IRQ source index within the source device
1965 * @dst_id: Device ID of the IRQ destination
1966 * @dst_host_irq: IRQ number of the destination device
1967 * @vint_irq: Boolean specifying if this interrupt belongs to
1968 * Interrupt Aggregator.
1969 *
1970 * Return: 0 if all went fine, else return appropriate error.
1971 */
1972static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
1973 u16 src_index, u16 dst_id, u16 dst_host_irq)
1974{
1975 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
1976
1977 return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id,
1978 dst_host_irq, 0, 0, 0, 0, 0);
1979}
1980
1981/**
1982 * ti_sci_cmd_free_event_map() - Free an event map between the requested source
1983 * and Interrupt Aggregator.
1984 * @handle: Pointer to TISCI handle.
1985 * @src_id: Device ID of the IRQ source
1986 * @src_index: IRQ source index within the source device
1987 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
1988 * @vint: Virtual interrupt to be used within the IA
1989 * @global_event: Global event number to be used for the requesting event
1990 * @vint_status_bit: Virtual interrupt status bit to be used for the event
1991 *
1992 * Return: 0 if all went fine, else return appropriate error.
1993 */
1994static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
1995 u16 src_id, u16 src_index, u16 ia_id,
1996 u16 vint, u16 global_event,
1997 u8 vint_status_bit)
1998{
1999 u32 valid_params = MSG_FLAG_IA_ID_VALID |
2000 MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
2001 MSG_FLAG_VINT_STS_BIT_VALID;
2002
2003 return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
2004 ia_id, vint, global_event, vint_status_bit, 0);
2005}
2006
1768/*2007/*
1769 * ti_sci_setup_ops() - Setup the operations structures2008 * ti_sci_setup_ops() - Setup the operations structures
1770 * @info: pointer to TISCI pointer2009 * @info: pointer to TISCI pointer
@@ -1776,6 +2015,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) · 5 unmodified lines
1776 struct ti_sci_dev_ops *dops = &ops->dev_ops;2015 struct ti_sci_dev_ops *dops = &ops->dev_ops;
1777 struct ti_sci_clk_ops *cops = &ops->clk_ops;2016 struct ti_sci_clk_ops *cops = &ops->clk_ops;
1778 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;2017 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
2018 struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
1779 2019
1780 core_ops->reboot_device = ti_sci_cmd_core_reboot;2020 core_ops->reboot_device = ti_sci_cmd_core_reboot;
1781 2021
@@ -1810,6 +2050,11 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) · 28 unmodified lines
1810 rm_core_ops->get_range = ti_sci_cmd_get_resource_range;2050 rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
1811 rm_core_ops->get_range_from_shost =2051 rm_core_ops->get_range_from_shost =
1812 ti_sci_cmd_get_resource_range_from_shost;2052 ti_sci_cmd_get_resource_range_from_shost;
2053
2054 iops->set_irq = ti_sci_cmd_set_irq;
2055 iops->set_event_map = ti_sci_cmd_set_event_map;
2056 iops->free_irq = ti_sci_cmd_free_irq;
2057 iops->free_event_map = ti_sci_cmd_free_event_map;
1813}2058}
1814 2059
1815/**2060/**
drivers/firmware/ti_sci.h+60−0
@@ -38,6 +38,10 @@ · 37 unmodified lines
38/* Resource Management Requests */38/* Resource Management Requests */
39#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x150039#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500
40 40
41/* IRQ requests */
42#define TI_SCI_MSG_SET_IRQ 0x1000
43#define TI_SCI_MSG_FREE_IRQ 0x1001
44
41/**45/**
42 * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses46 * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
43 * @type: Type of messages: One of TI_SCI_MSG* values47 * @type: Type of messages: One of TI_SCI_MSG* values
@@ -503,4 +507,60 @@ struct ti_sci_msg_resp_get_resource_range { · 459 unmodified lines
503 u16 range_num;507 u16 range_num;
504} __packed;508} __packed;
505 509
510/**
511 * struct ti_sci_msg_req_manage_irq - Request to configure/release the route
512 * between the dev and the host.
513 * @hdr: Generic Header
514 * @valid_params: Bit fields defining the validity of interrupt source
515 * parameters. If a bit is not set, then corresponding
516 * field is not valid and will not be used for route set.
517 * Bit field definitions:
518 * 0 - Valid bit for @dst_id
519 * 1 - Valid bit for @dst_host_irq
520 * 2 - Valid bit for @ia_id
521 * 3 - Valid bit for @vint
522 * 4 - Valid bit for @global_event
523 * 5 - Valid bit for @vint_status_bit_index
524 * 31 - Valid bit for @secondary_host
525 * @src_id: IRQ source peripheral ID.
526 * @src_index: IRQ source index within the peripheral
527 * @dst_id: IRQ Destination ID. Based on the architecture it can be
528 * IRQ controller or host processor ID.
529 * @dst_host_irq: IRQ number of the destination host IRQ controller
530 * @ia_id: Device ID of the interrupt aggregator in which the
531 * vint resides.
532 * @vint: Virtual interrupt number if the interrupt route
533 * is through an interrupt aggregator.
534 * @global_event: Global event that is to be mapped to interrupt
535 * aggregator virtual interrupt status bit.
536 * @vint_status_bit: Virtual interrupt status bit if the interrupt route
537 * utilizes an interrupt aggregator status bit.
538 * @secondary_host: Host ID of the IRQ destination computing entity. This is
539 * required only when destination host id is different
540 * from ti sci interface host id.
541 *
542 * Request type is TI_SCI_MSG_SET/RELEASE_IRQ.
543 * Response is generic ACK / NACK message.
544 */
545struct ti_sci_msg_req_manage_irq {
546 struct ti_sci_msg_hdr hdr;
547#define MSG_FLAG_DST_ID_VALID TI_SCI_MSG_FLAG(0)
548#define MSG_FLAG_DST_HOST_IRQ_VALID TI_SCI_MSG_FLAG(1)
549#define MSG_FLAG_IA_ID_VALID TI_SCI_MSG_FLAG(2)
550#define MSG_FLAG_VINT_VALID TI_SCI_MSG_FLAG(3)
551#define MSG_FLAG_GLB_EVNT_VALID TI_SCI_MSG_FLAG(4)
552#define MSG_FLAG_VINT_STS_BIT_VALID TI_SCI_MSG_FLAG(5)
553#define MSG_FLAG_SHOST_VALID TI_SCI_MSG_FLAG(31)
554 u32 valid_params;
555 u16 src_id;
556 u16 src_index;
557 u16 dst_id;
558 u16 dst_host_irq;
559 u16 ia_id;
560 u16 vint;
561 u16 global_event;
562 u8 vint_status_bit;
563 u8 secondary_host;
564} __packed;
565
506#endif /* __TI_SCI_H */566#endif /* __TI_SCI_H */
include/linux/soc/ti/ti_sci_protocol.h+26−0
@@ -217,17 +217,43 @@ struct ti_sci_rm_core_ops { · 216 unmodified lines
217 u16 *range_start, u16 *range_num);217 u16 *range_start, u16 *range_num);
218};218};
219 219
220/**
221 * struct ti_sci_rm_irq_ops: IRQ management operations
222 * @set_irq: Set an IRQ route between the requested source
223 * and destination
224 * @set_event_map: Set an Event based peripheral irq to Interrupt
225 * Aggregator.
226 * @free_irq: Free an an IRQ route between the requested source
227 * destination.
228 * @free_event_map: Free an event based peripheral irq to Interrupt
229 * Aggregator.
230 */
231struct ti_sci_rm_irq_ops {
232 int (*set_irq)(const struct ti_sci_handle *handle, u16 src_id,
233 u16 src_index, u16 dst_id, u16 dst_host_irq);
234 int (*set_event_map)(const struct ti_sci_handle *handle, u16 src_id,
235 u16 src_index, u16 ia_id, u16 vint,
236 u16 global_event, u8 vint_status_bit);
237 int (*free_irq)(const struct ti_sci_handle *handle, u16 src_id,
238 u16 src_index, u16 dst_id, u16 dst_host_irq);
239 int (*free_event_map)(const struct ti_sci_handle *handle, u16 src_id,
240 u16 src_index, u16 ia_id, u16 vint,
241 u16 global_event, u8 vint_status_bit);
242};
243
220/**244/**
221 * struct ti_sci_ops - Function support for TI SCI245 * struct ti_sci_ops - Function support for TI SCI
222 * @dev_ops: Device specific operations246 * @dev_ops: Device specific operations
223 * @clk_ops: Clock specific operations247 * @clk_ops: Clock specific operations
224 * @rm_core_ops: Resource management core operations.248 * @rm_core_ops: Resource management core operations.
249 * @rm_irq_ops: IRQ management specific operations
225 */250 */
226struct ti_sci_ops {251struct ti_sci_ops {
227 struct ti_sci_core_ops core_ops;252 struct ti_sci_core_ops core_ops;
228 struct ti_sci_dev_ops dev_ops;253 struct ti_sci_dev_ops dev_ops;
229 struct ti_sci_clk_ops clk_ops;254 struct ti_sci_clk_ops clk_ops;
230 struct ti_sci_rm_core_ops rm_core_ops;255 struct ti_sci_rm_core_ops rm_core_ops;
256 struct ti_sci_rm_irq_ops rm_irq_ops;
231};257};
232 258
233/**259/**

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t